def test_create_response_uri_generates_session_state_if_session_management_enabled(self):
        # RequestFactory doesn't support sessions, so we mock it
        self.request.session = mock.Mock(session_key=None)

        authorization_endpoint = AuthorizeEndpoint(self.request)
        authorization_endpoint.validate_params()

        uri = authorization_endpoint.create_response_uri()
        self.assertIn('session_state=', uri)
Esempio n. 2
0
    def test_create_response_uri_generates_session_state_if_session_management_enabled(self):
        # RequestFactory doesn't support sessions, so we mock it
        self.request.session = mock.Mock(session_key=None)

        authorization_endpoint = AuthorizeEndpoint(self.request)
        authorization_endpoint.validate_params()

        uri = authorization_endpoint.create_response_uri()
        self.assertIn('session_state=', uri)
Esempio n. 3
0
def validatePresentation(request):
    aut = AuthorizeEndpoint(request)
    try:
        aut.validate_params()
    except Exception as e:
        # return HttpResponseBadRequest(
        #     f"Error validating parameters: [{e.error}: {e.description}]"
        # )
        return HttpResponseBadRequest(
            f"Error validating parameters: [{e!r}: {e!r}]")
Esempio n. 4
0
    def post(self, request, *args, **kwargs):
        authorize = AuthorizeEndpoint(request)

        try:
            authorize.validate_params()

            if not request.POST.get('allow'):
                signals.user_decline_consent.send(
                    self.__class__,
                    user=request.user,
                    client=authorize.client,
                    scope=authorize.params['scope'])

                raise AuthorizeError(authorize.params['redirect_uri'],
                                     'access_denied', authorize.grant_type)

            signals.user_accept_consent.send(self.__class__,
                                             user=request.user,
                                             client=authorize.client,
                                             scope=authorize.params['scope'])

            # Save the user consent given to the client.
            authorize.set_client_user_consent()

            uri = authorize.create_response_uri()

            return redirect(uri)

        except AuthorizeError as error:
            uri = error.create_uri(authorize.params['redirect_uri'],
                                   authorize.params['state'])

            return redirect(uri)
    def test_create_response_uri_logs_to_error(self, log_exception, create_code):
        """
        A lot can go wrong when creating a response uri and this is caught
        with a general Exception error. The information contained within this
        error should show up in the error log so production servers have something
        to work with when things don't work as expected.
        """
        exception = Exception("Something went wrong!")
        create_code.side_effect = exception

        authorization_endpoint = AuthorizeEndpoint(self.request)
        authorization_endpoint.validate_params()

        with self.assertRaises(Exception):
            authorization_endpoint.create_response_uri()

        log_exception.assert_called_once_with(
            '[Authorize] Error when trying to create response uri: %s', exception)
Esempio n. 6
0
def authorize(request):
    template_name = "qr_display.html"

    if request.method == "GET":
        pres_req_conf_id = request.GET.get("pres_req_conf_id")
        if not pres_req_conf_id:
            return HttpResponseBadRequest(
                "pres_req_conf_id query parameter not found")

        scopes = request.GET.get("scope")
        if not scopes or "vc_authn" not in scopes.split(" "):
            return HttpResponseBadRequest("Scope vc_authn not found")

        aut = AuthorizeEndpoint(request)
        try:
            aut.validate_params()
        except Exception as e:
            return HttpResponseBadRequest(
                f"Error validating parameters: [{e.error}: {e.description}]")

        short_url, session_id, pres_req, b64_presentation = authorization(
            pres_req_conf_id, request.GET)
        request.session["sessionid"] = session_id

        return TemplateResponse(
            request,
            template_name,
            {
                "url":
                short_url,
                "b64_presentation":
                b64_presentation,
                "poll_interval":
                settings.POLL_INTERVAL,
                "poll_max_tries":
                settings.POLL_MAX_TRIES,
                "poll_url":
                f"{settings.SITE_URL}/vc/connect/poll?pid={pres_req}",
                "resolution_url":
                f"{settings.SITE_URL}/vc/connect/callback?pid={pres_req}",
            },
        )
Esempio n. 7
0
    def post(self, request, *args, **kwargs):
        authorize = AuthorizeEndpoint(request)

        try:
            authorize.validate_params()

            if not request.POST.get('allow'):
                signals.user_decline_consent.send(
                    self.__class__, user=request.user,
                    client=authorize.client, scope=authorize.params['scope'])

                raise AuthorizeError(authorize.params['redirect_uri'],
                                     'access_denied',
                                     authorize.grant_type)

            signals.user_accept_consent.send(
                self.__class__, user=request.user, client=authorize.client,
                scope=authorize.params['scope'])

            # Save the user consent given to the client.
            authorize.set_client_user_consent()

            uri = authorize.create_response_uri()

            return redirect(uri)

        except AuthorizeError as error:
            uri = error.create_uri(
                authorize.params['redirect_uri'],
                authorize.params['state'])

            return redirect(uri)
Esempio n. 8
0
def get_return_to_rp_uri(request, redirect_uri_params):
    """Returns an URI to redirect the browser to if user cancels authentication
    """

    params = {key: val[0] for key, val in redirect_uri_params.items()}
    dummy_request = DummyRequest(params)
    authorize = AuthorizeEndpoint(dummy_request)
    try:
        # This will make sure redirect URI is valid.
        authorize.validate_params()
    except (
        oidc_errors.ClientIdError, oidc_errors.RedirectUriError, oidc_errors.AuthorizeError
    ):
        return None

    cancel_error = oidc_errors.AuthorizeError(
        authorize.params['redirect_uri'], 'access_denied', authorize.grant_type
    )
    return_uri = cancel_error.create_uri(
        authorize.params['redirect_uri'],
        authorize.params['state']
    )
    return return_uri
Esempio n. 9
0
    def test_create_response_uri_logs_to_error(self, log_exception, create_code):
        """
        A lot can go wrong when creating a response uri and this is caught
        with a general Exception error. The information contained within this
        error should show up in the error log so production servers have something
        to work with when things don't work as expected.
        """
        exception = Exception("Something went wrong!")
        create_code.side_effect = exception

        authorization_endpoint = AuthorizeEndpoint(self.request)
        authorization_endpoint.validate_params()

        with self.assertRaises(Exception):
            authorization_endpoint.create_response_uri()

        log_exception.assert_called_once_with(
            '[Authorize] Error when trying to create response uri: %s', exception)
Esempio n. 10
0
    def post(self, request, *args, **kwargs):
        authorize = AuthorizeEndpoint(request)

        try:
            authorize.validate_params()

            if not request.POST.get('allow'):
                raise AuthorizeError(authorize.params['redirect_uri'],
                                     'access_denied', authorize.grant_type)

            # Save the user consent given to the client.
            authorize.set_client_user_consent()

            uri = authorize.create_response_uri()

            return redirect(uri)

        except (AuthorizeError) as error:
            uri = error.create_uri(authorize.params['redirect_uri'],
                                   authorize.params['state'])

            return redirect(uri)
Esempio n. 11
0
    def post(self, request, *args, **kwargs):
        authorize = AuthorizeEndpoint(request)

        try:
            authorize.validate_params()

            if not request.POST.get('allow'):
                raise AuthorizeError(authorize.params.redirect_uri,
                                     'access_denied',
                                     authorize.grant_type)

            # Save the user consent given to the client.
            authorize.set_client_user_consent()

            uri = authorize.create_response_uri()

            return redirect(uri)

        except (AuthorizeError) as error:
            uri = error.create_uri(
                authorize.params.redirect_uri,
                authorize.params.state)

            return redirect(uri)
Esempio n. 12
0
    def get(self, request, *args, **kwargs):

        authorize = AuthorizeEndpoint(request)

        try:
            authorize.validate_params()

            if request.user.is_authenticated():
                # Check if there's a hook setted.
                hook_resp = settings.get('OIDC_AFTER_USERLOGIN_HOOK',
                                         import_str=True)(
                                             request=request,
                                             user=request.user,
                                             client=authorize.client)
                if hook_resp:
                    return hook_resp

                if settings.get('OIDC_SKIP_CONSENT_ALWAYS') and not (authorize.client.client_type == 'public') \
                and not (authorize.params['prompt'] == 'consent'):
                    return redirect(authorize.create_response_uri())

                if settings.get('OIDC_SKIP_CONSENT_ENABLE'):
                    # Check if user previously give consent.
                    if authorize.client_has_user_consent() and not (authorize.client.client_type == 'public') \
                    and not (authorize.params['prompt'] == 'consent'):
                        return redirect(authorize.create_response_uri())

                if authorize.params['prompt'] == 'none':
                    raise AuthorizeError(authorize.params['redirect_uri'],
                                         'interaction_required',
                                         authorize.grant_type)

                if authorize.params['prompt'] == 'login':
                    return redirect_to_login(request.get_full_path())

                if authorize.params['prompt'] == 'select_account':
                    # TODO: see how we can support multiple accounts for the end-user.
                    raise AuthorizeError(authorize.params['redirect_uri'],
                                         'account_selection_required',
                                         authorize.grant_type)

                # Generate hidden inputs for the form.
                context = {
                    'params': authorize.params,
                }
                hidden_inputs = render_to_string(
                    'oidc_provider/hidden_inputs.html', context)

                # Remove `openid` from scope list
                # since we don't need to print it.
                if 'openid' in authorize.params['scope']:
                    authorize.params['scope'].remove('openid')

                context = {
                    'client': authorize.client,
                    'hidden_inputs': hidden_inputs,
                    'params': authorize.params,
                    'scopes': authorize.get_scopes_information(),
                }

                return render(request, 'oidc_provider/authorize.html', context)
            else:
                if authorize.params['prompt'] == 'none':
                    raise AuthorizeError(authorize.params['redirect_uri'],
                                         'login_required',
                                         authorize.grant_type)

                return redirect_to_login(request.get_full_path())

        except (ClientIdError, RedirectUriError) as error:
            context = {
                'error': error.error,
                'description': error.description,
            }

            return render(request, 'oidc_provider/error.html', context)

        except (AuthorizeError) as error:
            uri = error.create_uri(authorize.params['redirect_uri'],
                                   authorize.params['state'])

            return redirect(uri)
Esempio n. 13
0
    def get(self, request, *args, **kwargs):

        authorize = AuthorizeEndpoint(request)

        try:
            authorize.validate_params()

            if request.user.is_authenticated():
                # Check if there's a hook setted.
                hook_resp = settings.get('OIDC_AFTER_USERLOGIN_HOOK', import_str=True)(
                    request=request, user=request.user,
                    client=authorize.client)
                if hook_resp:
                    return hook_resp

                if settings.get('OIDC_SKIP_CONSENT_ALWAYS') and not (authorize.client.client_type == 'public') \
                and not (authorize.params.prompt == 'consent'):
                    return redirect(authorize.create_response_uri())

                if settings.get('OIDC_SKIP_CONSENT_ENABLE'):
                    # Check if user previously give consent.
                    if authorize.client_has_user_consent() and not (authorize.client.client_type == 'public') \
                    and not (authorize.params.prompt == 'consent'):
                        return redirect(authorize.create_response_uri())

                if authorize.params.prompt == 'none':
                    raise AuthorizeError(authorize.params.redirect_uri, 'interaction_required', authorize.grant_type)

                if authorize.params.prompt == 'login':
                    return redirect_to_login(request.get_full_path())

                if authorize.params.prompt == 'select_account':
                    # TODO: see how we can support multiple accounts for the end-user.
                    raise AuthorizeError(authorize.params.redirect_uri, 'account_selection_required', authorize.grant_type)

                # Generate hidden inputs for the form.
                context = {
                    'params': authorize.params,
                }
                hidden_inputs = render_to_string('oidc_provider/hidden_inputs.html', context)

                # Remove `openid` from scope list
                # since we don't need to print it.
                if 'openid' in authorize.params.scope:
                    authorize.params.scope.remove('openid')

                context = {
                    'client': authorize.client,
                    'hidden_inputs': hidden_inputs,
                    'params': authorize.params,
                    'scopes': authorize.get_scopes_information(),
                }

                return render(request, 'oidc_provider/authorize.html', context)
            else:
                if authorize.params.prompt == 'none':
                    raise AuthorizeError(authorize.params.redirect_uri, 'login_required', authorize.grant_type)

                return redirect_to_login(request.get_full_path())

        except (ClientIdError, RedirectUriError) as error:
            context = {
                'error': error.error,
                'description': error.description,
            }

            return render(request, 'oidc_provider/error.html', context)

        except (AuthorizeError) as error:
            uri = error.create_uri(
                authorize.params.redirect_uri,
                authorize.params.state)

            return redirect(uri)
Esempio n. 14
0
    def get(self, request, *args, **kwargs):

        authorize = AuthorizeEndpoint(request)

        try:
            authorize.validate_params()

            if get_attr_or_callable(request.user, 'is_authenticated'):
                # Check if there's a hook setted.
                hook_resp = settings.get('OIDC_AFTER_USERLOGIN_HOOK',
                                         import_str=True)(
                                             request=request,
                                             user=request.user,
                                             client=authorize.client)
                if hook_resp:
                    return hook_resp

                if 'login' in authorize.params['prompt']:
                    if 'none' in authorize.params['prompt']:
                        raise AuthorizeError(authorize.params['redirect_uri'],
                                             'login_required',
                                             authorize.grant_type)
                    else:
                        django_user_logout(request)
                        next_page = self.strip_prompt_login(
                            request.get_full_path())
                        return redirect_to_login(
                            next_page, settings.get('OIDC_LOGIN_URL'))

                if 'select_account' in authorize.params['prompt']:
                    # TODO: see how we can support multiple accounts for the end-user.
                    if 'none' in authorize.params['prompt']:
                        raise AuthorizeError(authorize.params['redirect_uri'],
                                             'account_selection_required',
                                             authorize.grant_type)
                    else:
                        django_user_logout(request)
                        return redirect_to_login(
                            request.get_full_path(),
                            settings.get('OIDC_LOGIN_URL'))

                if {'none', 'consent'}.issubset(authorize.params['prompt']):
                    raise AuthorizeError(authorize.params['redirect_uri'],
                                         'consent_required',
                                         authorize.grant_type)

                implicit_flow_resp_types = {'id_token', 'id_token token'}
                allow_skipping_consent = (
                    authorize.client.client_type != 'public' or
                    authorize.client.response_type in implicit_flow_resp_types)

                if not authorize.client.require_consent and (
                        'consent' not in authorize.params['prompt']):
                    return redirect(authorize.create_response_uri())

                if authorize.client.reuse_consent:
                    # Check if user previously give consent.
                    if authorize.client_has_user_consent() and (
                            'consent' not in authorize.params['prompt']):
                        return redirect(authorize.create_response_uri())

                if 'none' in authorize.params['prompt']:
                    raise AuthorizeError(authorize.params['redirect_uri'],
                                         'consent_required',
                                         authorize.grant_type)

                # Generate hidden inputs for the form.
                context = {
                    'params': authorize.params,
                }
                hidden_inputs = render_to_string(
                    'oidc_provider/hidden_inputs.html', context)

                # Remove `openid` from scope list
                # since we don't need to print it.
                if 'openid' in authorize.params['scope']:
                    authorize.params['scope'].remove('openid')

                context = {
                    'client': authorize.client,
                    'hidden_inputs': hidden_inputs,
                    'params': authorize.params,
                    'scopes': authorize.get_scopes_information()
                }

                return render(request, OIDC_TEMPLATES['authorize'], context)
            else:
                if 'none' in authorize.params['prompt']:
                    raise AuthorizeError(authorize.params['redirect_uri'],
                                         'login_required',
                                         authorize.grant_type)
                if 'login' in authorize.params['prompt']:
                    next_page = self.strip_prompt_login(
                        request.get_full_path())
                    return redirect_to_login(next_page,
                                             settings.get('OIDC_LOGIN_URL'))

                return redirect_to_login(request.get_full_path(),
                                         settings.get('OIDC_LOGIN_URL'))

        except (ClientIdError, RedirectUriError) as error:
            context = {
                'error': error.error,
                'description': error.description,
            }

            return render(request, OIDC_TEMPLATES['error'], context)

        except AuthorizeError as error:
            uri = error.create_uri(authorize.params['redirect_uri'],
                                   authorize.params['state'])

            return redirect(uri)