123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192 |
- # GNU MediaGoblin -- federated, autonomous media hosting
- # Copyright (C) 2011, 2012 MediaGoblin contributors. See AUTHORS.
- #
- # This program is free software: you can redistribute it and/or modify
- # it under the terms of the GNU Affero General Public License as published by
- # the Free Software Foundation, either version 3 of the License, or
- # (at your option) any later version.
- #
- # This program is distributed in the hope that it will be useful,
- # but WITHOUT ANY WARRANTY; without even the implied warranty of
- # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- # GNU Affero General Public License for more details.
- #
- # You should have received a copy of the GNU Affero General Public License
- # along with this program. If not, see <http://www.gnu.org/licenses/>.
- import datetime
- from oauthlib.common import Request
- from oauthlib.oauth1 import RequestValidator
- from mediagoblin import oauth
- from mediagoblin.db.models import NonceTimestamp, Client, RequestToken, AccessToken
- class GMGRequestValidator(RequestValidator):
- enforce_ssl = False
- def __init__(self, data=None, *args, **kwargs):
- self.POST = data
- super(GMGRequestValidator, self).__init__(*args, **kwargs)
- def check_nonce(self, nonce):
- """
- This checks that the nonce given is a valid nonce
- RequestValidator.check_nonce checks that it's between a maximum and
- minimum length which, not only does pump.io not do this from what
- I can see but there is nothing in rfc5849 which suggests a maximum or
- minium length should be required so I'm removing that check
- """
- # Check the nonce only contains a subset of the safe characters.
- return set(nonce) <= self.safe_characters
- def save_request_token(self, token, request):
- """ Saves request token in db """
- client_id = self.POST[u"oauth_consumer_key"]
- request_token = RequestToken(
- token=token["oauth_token"],
- secret=token["oauth_token_secret"],
- )
- request_token.client = client_id
- if u"oauth_callback" in self.POST:
- request_token.callback = self.POST[u"oauth_callback"]
- request_token.save()
- def save_verifier(self, token, verifier, request):
- """ Saves the oauth request verifier """
- request_token = RequestToken.query.filter_by(token=token).first()
- request_token.verifier = verifier["oauth_verifier"]
- request_token.save()
- def save_access_token(self, token, request):
- """ Saves access token in db """
- access_token = AccessToken(
- token=token["oauth_token"],
- secret=token["oauth_token_secret"],
- )
- access_token.request_token = request.oauth_token
- request_token = RequestToken.query.filter_by(token=request.oauth_token).first()
- access_token.actor = request_token.actor
- access_token.save()
- def get_realms(*args, **kwargs):
- """ Currently a stub - called when making AccessTokens """
- return list()
- def validate_timestamp_and_nonce(self, client_key, timestamp,
- nonce, request, request_token=None,
- access_token=None):
- # RFC5849 (OAuth 1.0) section 3.3 says the timestamp is going
- # to be seconds after the epoch, we need to convert for postgres
- try:
- timestamp = datetime.datetime.fromtimestamp(float(timestamp))
- except ValueError:
- # Well, the client must have passed up something ridiculous
- return False
- nc = NonceTimestamp.query.filter_by(timestamp=timestamp, nonce=nonce)
- nc = nc.first()
- if nc is None:
- return True
- return False
- def validate_client_key(self, client_key, request):
- """ Verifies client exists with id of client_key """
- client_query = Client.query.filter(Client.id != oauth.DUMMY_CLIENT_ID)
- client = client_query.filter_by(id=client_key).first()
- if client is None:
- return False
- return True
- def validate_verifier(self, token, verifier):
- """ Verifies the verifier token is correct. """
- request_token = RequestToken.query.filter_by(token=token).first()
- if request_token is None:
- return False
- if request_token.verifier != verifier:
- return False
- return True
- def validate_access_token(self, client_key, token, request):
- """ Verifies token exists for client with id of client_key """
- # Get the client for the request
- client_query = Client.query.filter(Client.id != oauth.DUMMY_CLIENT_ID)
- client = client_query.filter_by(id=client_key).first()
- # If the client is invalid then it's invalid
- if client is None:
- return False
- # Look up the AccessToken
- access_token_query = AccessToken.query.filter(
- AccessToken.token != oauth.DUMMY_ACCESS_TOKEN
- )
- access_token = access_token_query.filter_by(token=token).first()
- # If there isn't one - we can't validate.
- if access_token is None:
- return False
- # Check that the client matches the on
- request_token_query = RequestToken.query.filter(
- RequestToken.token != oauth.DUMMY_REQUEST_TOKEN,
- RequestToken.token == access_token.request_token
- )
- request_token = request_token_query.first()
- if client.id != request_token.client:
- return False
- return True
- def validate_realms(self, *args, **kwargs):
- """ Would validate reals however not using these yet. """
- return True # implement when realms are implemented
- def get_client_secret(self, client_key, request):
- """ Retrives a client secret with from a client with an id of client_key """
- client = Client.query.filter_by(id=client_key).first()
- return client.secret
- def get_access_token_secret(self, client_key, token, request):
- access_token = AccessToken.query.filter_by(token=token).first()
- return access_token.secret
- @property
- def dummy_client(self):
- return oauth.DUMMY_CLIENT_ID
- @property
- def dummy_request_token(self):
- return oauth.DUMMY_REQUEST_TOKEN
- @property
- def dummy_access_token(self):
- return oauth.DUMMY_ACCESS_TOKEN
- class GMGRequest(Request):
- """
- Fills in data to produce a oauth.common.Request object from a
- werkzeug Request object
- """
- def __init__(self, request, *args, **kwargs):
- """
- :param request: werkzeug request object
- any extra params are passed to oauthlib.common.Request object
- """
- kwargs["uri"] = kwargs.get("uri", request.url)
- kwargs["http_method"] = kwargs.get("http_method", request.method)
- kwargs["body"] = kwargs.get("body", request.data)
- kwargs["headers"] = kwargs.get("headers", dict(request.headers))
- super(GMGRequest, self).__init__(*args, **kwargs)
|