123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158 |
- # -*- coding: utf-8 -*-
- """
- oauthlib.oauth1.rfc5849.endpoints.authorization
- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
- This module is an implementation of various logic needed
- for signing and checking OAuth 1.0 RFC 5849 requests.
- """
- from urllib.parse import urlencode
- from oauthlib.common import add_params_to_uri
- from .. import errors
- from .base import BaseEndpoint
- class AuthorizationEndpoint(BaseEndpoint):
- """An endpoint responsible for letting authenticated users authorize access
- to their protected resources to a client.
- Typical use would be to have two views, one for displaying the authorization
- form and one to process said form on submission.
- The first view will want to utilize ``get_realms_and_credentials`` to fetch
- requested realms and useful client credentials, such as name and
- description, to be used when creating the authorization form.
- During form processing you can use ``create_authorization_response`` to
- validate the request, create a verifier as well as prepare the final
- redirection URI used to send the user back to the client.
- See :doc:`/oauth1/validator` for details on which validator methods to implement
- for this endpoint.
- """
- def create_verifier(self, request, credentials):
- """Create and save a new request token.
- :param request: OAuthlib request.
- :type request: oauthlib.common.Request
- :param credentials: A dict of extra token credentials.
- :returns: The verifier as a dict.
- """
- verifier = {
- 'oauth_token': request.resource_owner_key,
- 'oauth_verifier': self.token_generator(),
- }
- verifier.update(credentials)
- self.request_validator.save_verifier(
- request.resource_owner_key, verifier, request)
- return verifier
- def create_authorization_response(self, uri, http_method='GET', body=None,
- headers=None, realms=None, credentials=None):
- """Create an authorization response, with a new request token if valid.
- :param uri: The full URI of the token request.
- :param http_method: A valid HTTP verb, i.e. GET, POST, PUT, HEAD, etc.
- :param body: The request body as a string.
- :param headers: The request headers as a dict.
- :param credentials: A list of credentials to include in the verifier.
- :returns: A tuple of 3 elements.
- 1. A dict of headers to set on the response.
- 2. The response body as a string.
- 3. The response status code as an integer.
- If the callback URI tied to the current token is "oob", a response with
- a 200 status code will be returned. In this case, it may be desirable to
- modify the response to better display the verifier to the client.
- An example of an authorization request::
- >>> from your_validator import your_validator
- >>> from oauthlib.oauth1 import AuthorizationEndpoint
- >>> endpoint = AuthorizationEndpoint(your_validator)
- >>> h, b, s = endpoint.create_authorization_response(
- ... 'https://your.provider/authorize?oauth_token=...',
- ... credentials={
- ... 'extra': 'argument',
- ... })
- >>> h
- {'Location': 'https://the.client/callback?oauth_verifier=...&extra=argument'}
- >>> b
- None
- >>> s
- 302
- An example of a request with an "oob" callback::
- >>> from your_validator import your_validator
- >>> from oauthlib.oauth1 import AuthorizationEndpoint
- >>> endpoint = AuthorizationEndpoint(your_validator)
- >>> h, b, s = endpoint.create_authorization_response(
- ... 'https://your.provider/authorize?foo=bar',
- ... credentials={
- ... 'extra': 'argument',
- ... })
- >>> h
- {'Content-Type': 'application/x-www-form-urlencoded'}
- >>> b
- 'oauth_verifier=...&extra=argument'
- >>> s
- 200
- """
- request = self._create_request(uri, http_method=http_method, body=body,
- headers=headers)
- if not request.resource_owner_key:
- raise errors.InvalidRequestError(
- 'Missing mandatory parameter oauth_token.')
- if not self.request_validator.verify_request_token(
- request.resource_owner_key, request):
- raise errors.InvalidClientError()
- request.realms = realms
- if (request.realms and not self.request_validator.verify_realms(
- request.resource_owner_key, request.realms, request)):
- raise errors.InvalidRequestError(
- description=('User granted access to realms outside of '
- 'what the client may request.'))
- verifier = self.create_verifier(request, credentials or {})
- redirect_uri = self.request_validator.get_redirect_uri(
- request.resource_owner_key, request)
- if redirect_uri == 'oob':
- response_headers = {
- 'Content-Type': 'application/x-www-form-urlencoded'}
- response_body = urlencode(verifier)
- return response_headers, response_body, 200
- else:
- populated_redirect = add_params_to_uri(
- redirect_uri, verifier.items())
- return {'Location': populated_redirect}, None, 302
- def get_realms_and_credentials(self, uri, http_method='GET', body=None,
- headers=None):
- """Fetch realms and credentials for the presented request token.
- :param uri: The full URI of the token request.
- :param http_method: A valid HTTP verb, i.e. GET, POST, PUT, HEAD, etc.
- :param body: The request body as a string.
- :param headers: The request headers as a dict.
- :returns: A tuple of 2 elements.
- 1. A list of request realms.
- 2. A dict of credentials which may be useful in creating the
- authorization form.
- """
- request = self._create_request(uri, http_method=http_method, body=body,
- headers=headers)
- if not self.request_validator.verify_request_token(
- request.resource_owner_key, request):
- raise errors.InvalidClientError()
- realms = self.request_validator.get_realms(
- request.resource_owner_key, request)
- return realms, {'resource_owner_key': request.resource_owner_key}
|