Finishes most of oauth, just decorator to complete
This commit is contained in:
parent
405aa45adc
commit
2b60a56cbe
@ -22,7 +22,8 @@ from werkzeug.exceptions import Forbidden, NotFound
|
||||
from mediagoblin import mg_globals as mgg
|
||||
from mediagoblin import messages
|
||||
from mediagoblin.db.models import MediaEntry, User
|
||||
from mediagoblin.tools.response import redirect, render_404
|
||||
from mediagoblin.tools.request import decode_authorization_header
|
||||
from mediagoblin.tools.response import json_response, redirect, render_404
|
||||
from mediagoblin.tools.translate import pass_to_ugettext as _
|
||||
|
||||
|
||||
@ -268,3 +269,16 @@ def auth_enabled(controller):
|
||||
return controller(request, *args, **kwargs)
|
||||
|
||||
return wrapper
|
||||
|
||||
def oauth_requeired(controller):
|
||||
""" Used to wrap API endpoints where oauth is required """
|
||||
@wraps(controller)
|
||||
def wrapper(request, *args, **kwargs):
|
||||
data = request.headers
|
||||
authorization = decode_authorization_header(data)
|
||||
|
||||
if authorization == dict():
|
||||
error = "Missing required parameter."
|
||||
return json_response({"error": error}, status=400)
|
||||
|
||||
|
||||
|
@ -18,14 +18,15 @@ import datetime
|
||||
|
||||
import oauthlib.common
|
||||
from oauthlib.oauth1 import (AuthorizationEndpoint, RequestValidator,
|
||||
RequestTokenEndpoint)
|
||||
RequestTokenEndpoint, AccessTokenEndpoint)
|
||||
|
||||
from mediagoblin.decorators import require_active_login
|
||||
from mediagoblin.tools.translate import pass_to_ugettext
|
||||
from mediagoblin.meddleware.csrf import csrf_exempt
|
||||
from mediagoblin.tools.request import decode_request
|
||||
from mediagoblin.tools.request import decode_request, decode_authorization_header
|
||||
from mediagoblin.tools.response import (render_to_response, redirect,
|
||||
json_response, render_400)
|
||||
json_response, render_400,
|
||||
form_response)
|
||||
from mediagoblin.tools.crypto import random_string
|
||||
from mediagoblin.tools.validator import validate_email, validate_url
|
||||
from mediagoblin.db.models import User, Client, RequestToken, AccessToken
|
||||
@ -184,7 +185,7 @@ class GMGRequestValidator(RequestValidator):
|
||||
|
||||
def save_request_token(self, token, request):
|
||||
""" Saves request token in db """
|
||||
client_id = self.POST[u"Authorization"][u"oauth_consumer_key"]
|
||||
client_id = self.POST[u"oauth_consumer_key"]
|
||||
|
||||
request_token = RequestToken(
|
||||
token=token["oauth_token"],
|
||||
@ -200,17 +201,21 @@ class GMGRequestValidator(RequestValidator):
|
||||
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_secret"],
|
||||
secret=token["oauth_token_secret"],
|
||||
)
|
||||
access_token.request_token = request.body["oauth_token"]
|
||||
access_token.user = token["user"].id
|
||||
access_token.request_token = request.oauth_token
|
||||
request_token = RequestToken.query.filter_by(token=request.oauth_token).first()
|
||||
access_token.user = request_token.user
|
||||
access_token.save()
|
||||
|
||||
def get_realms(*args, **kwargs):
|
||||
""" Currently a stub - called when making AccessTokens """
|
||||
return list()
|
||||
|
||||
@csrf_exempt
|
||||
def request_token(request):
|
||||
""" Returns request token """
|
||||
@ -224,45 +229,32 @@ def request_token(request):
|
||||
error = "Unknown Content-Type"
|
||||
return json_response({"error": error}, status=400)
|
||||
|
||||
print data
|
||||
if not data and request.headers:
|
||||
data = request.headers
|
||||
|
||||
if "Authorization" not in data:
|
||||
data = dict(data) # mutableifying
|
||||
|
||||
authorization = decode_authorization_header(data)
|
||||
|
||||
|
||||
if authorization == dict() or u"oauth_consumer_key" not in authorization:
|
||||
error = "Missing required parameter."
|
||||
return json_response({"error": error}, status=400)
|
||||
|
||||
|
||||
# Convert 'Authorization' to a dictionary
|
||||
authorization = {}
|
||||
for item in data["Authorization"].split(","):
|
||||
key, value = item.split("=", 1)
|
||||
authorization[key] = value
|
||||
data[u"Authorization"] = authorization
|
||||
|
||||
if "oauth_consumer_key" not in data[u"Authorization"]:
|
||||
error = "Missing required parameter."
|
||||
return json_respinse({"error": error}, status=400)
|
||||
|
||||
# check the client_id
|
||||
client_id = data[u"Authorization"][u"oauth_consumer_key"]
|
||||
client_id = authorization[u"oauth_consumer_key"]
|
||||
client = Client.query.filter_by(id=client_id).first()
|
||||
if client is None:
|
||||
# client_id is invalid
|
||||
error = "Invalid client_id"
|
||||
return json_response({"error": error}, status=400)
|
||||
|
||||
request_validator = GMGRequestValidator(data)
|
||||
# make request token and return to client
|
||||
request_validator = GMGRequestValidator(authorization)
|
||||
rv = RequestTokenEndpoint(request_validator)
|
||||
tokens = rv.create_request_token(request, authorization)
|
||||
|
||||
tokenized = {}
|
||||
for t in tokens.split("&"):
|
||||
key, value = t.split("=")
|
||||
tokenized[key] = value
|
||||
|
||||
print "[DEBUG] %s" % tokenized
|
||||
|
||||
# check what encoding to return them in
|
||||
return json_response(tokenized)
|
||||
return form_response(tokens)
|
||||
|
||||
class WTFormData(dict):
|
||||
"""
|
||||
@ -375,14 +367,18 @@ def authorize_finish(request):
|
||||
@csrf_exempt
|
||||
def access_token(request):
|
||||
""" Provides an access token based on a valid verifier and request token """
|
||||
try:
|
||||
data = decode_request(request)
|
||||
except ValueError:
|
||||
error = "Could not decode data."
|
||||
data = request.headers
|
||||
|
||||
parsed_tokens = decode_authorization_header(data)
|
||||
|
||||
if parsed_tokens == dict() or "oauth_token" not in parsed_tokens:
|
||||
error = "Missing required parameter."
|
||||
return json_response({"error": error}, status=400)
|
||||
|
||||
if data == "":
|
||||
error = "Unknown Content-Type"
|
||||
return json_response({"error": error}, status=400)
|
||||
|
||||
print "debug: %s" % data
|
||||
request.oauth_token = parsed_tokens["oauth_token"]
|
||||
request_validator = GMGRequestValidator(data)
|
||||
av = AccessTokenEndpoint(request_validator)
|
||||
tokens = av.create_access_token(request, {})
|
||||
return form_response(tokens)
|
||||
|
||||
|
@ -14,6 +14,7 @@
|
||||
# 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 re
|
||||
import json
|
||||
import logging
|
||||
from mediagoblin.db.models import User
|
||||
@ -25,6 +26,9 @@ _log = logging.getLogger(__name__)
|
||||
form_encoded = "application/x-www-form-urlencoded"
|
||||
json_encoded = "application/json"
|
||||
|
||||
# Regex for Authorization header
|
||||
auth_header_re = re.compile('(\w+)[:=] ?"?(\w+)"?')
|
||||
|
||||
def setup_user_in_request(request):
|
||||
"""
|
||||
Examine a request and tack on a request.user parameter if that's
|
||||
@ -53,3 +57,9 @@ def decode_request(request):
|
||||
else:
|
||||
data = ""
|
||||
return data
|
||||
|
||||
def decode_authorization_header(header):
|
||||
""" Decodes a HTTP Authorization Header to python dictionary """
|
||||
authorization = header.get("Authorization", "")
|
||||
tokens = dict(auth_header_re.findall(authorization))
|
||||
return tokens
|
||||
|
@ -138,3 +138,22 @@ def json_response(serializable, _disable_cors=False, *args, **kw):
|
||||
response.headers.set(key, value)
|
||||
|
||||
return response
|
||||
|
||||
def form_response(data, *args, **kwargs):
|
||||
"""
|
||||
Responds using application/x-www-form-urlencoded and returns a werkzeug
|
||||
Response object with the data argument as the body
|
||||
and 'application/x-www-form-urlencoded' as the Content-Type.
|
||||
|
||||
Any extra arguments and keyword arguments are passed to the
|
||||
Response.__init__ method.
|
||||
"""
|
||||
|
||||
response = wz_Response(
|
||||
data,
|
||||
content_type="application/x-www-form-urlencoded",
|
||||
*args,
|
||||
**kwargs
|
||||
)
|
||||
|
||||
return response
|
||||
|
Loading…
x
Reference in New Issue
Block a user