Working client registration
This commit is contained in:
parent
c840cb6618
commit
4990b47ce4
@ -105,6 +105,29 @@ class User(Base, UserMixin):
|
||||
_log.info('Deleted user "{0}" account'.format(self.username))
|
||||
|
||||
|
||||
class Client(Base):
|
||||
"""
|
||||
Model representing a client - Used for API Auth
|
||||
"""
|
||||
__tablename__ = "core__clients"
|
||||
|
||||
id = Column(Unicode, nullable=True, primary_key=True)
|
||||
secret = Column(Unicode, nullable=False)
|
||||
expirey = Column(DateTime, nullable=True)
|
||||
application_type = Column(Unicode, nullable=False)
|
||||
created = Column(DateTime, nullable=False, default=datetime.datetime.now)
|
||||
updated = Column(DateTime, nullable=False, default=datetime.datetime.now)
|
||||
|
||||
# optional stuff
|
||||
redirect_uri = Column(Unicode, nullable=True)
|
||||
logo_uri = Column(Unicode, nullable=True)
|
||||
application_name = Column(Unicode, nullable=True)
|
||||
|
||||
def __repr__(self):
|
||||
return "<Client {0}>".format(self.id)
|
||||
|
||||
|
||||
|
||||
class MediaEntry(Base, MediaEntryMixin):
|
||||
"""
|
||||
TODO: Consider fetching the media_files using join
|
||||
@ -580,7 +603,7 @@ with_polymorphic(
|
||||
[ProcessingNotification, CommentNotification])
|
||||
|
||||
MODELS = [
|
||||
User, MediaEntry, Tag, MediaTag, MediaComment, Collection, CollectionItem,
|
||||
User, Client, MediaEntry, Tag, MediaTag, MediaComment, Collection, CollectionItem,
|
||||
MediaFile, FileKeynames, MediaAttachmentFile, ProcessingMetaData,
|
||||
Notification, CommentNotification, ProcessingNotification,
|
||||
CommentSubscription]
|
||||
|
@ -14,21 +14,47 @@
|
||||
# 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/>.
|
||||
|
||||
from mediagoblin.tools.json import json_response
|
||||
import json
|
||||
|
||||
from mediagoblin.meddleware.csrf import csrf_exempt
|
||||
from mediagoblin.tools.response import json_response
|
||||
from mediagoblin.tools.crypto import random_string
|
||||
from mediagoblin.db.models import Client
|
||||
|
||||
# possible client types
|
||||
client_types = ["web", "native"] # currently what pump supports
|
||||
|
||||
@csrf_exempt
|
||||
def client_register(request):
|
||||
""" Endpoint for client registration """
|
||||
if request.method == "POST":
|
||||
# new client registration
|
||||
data = request.get_data()
|
||||
if request.content_type == "application/json":
|
||||
try:
|
||||
data = json.loads(data)
|
||||
except ValueError:
|
||||
return json_response({"error":"Could not decode JSON"})
|
||||
else:
|
||||
return json_response({"error":"Unknown Content-Type"}, status=400)
|
||||
|
||||
return json_response({"dir":dir(request)})
|
||||
if "type" not in data:
|
||||
return json_response({"error":"No registration type provided"}, status=400)
|
||||
|
||||
# check they haven't given us client_id or client_type, they're only used for updating
|
||||
pass
|
||||
# generate the client_id and client_secret
|
||||
client_id = random_string(22) # seems to be what pump uses
|
||||
client_secret = random_string(43) # again, seems to be what pump uses
|
||||
expirey = 0 # for now, lets not have it expire
|
||||
expirey_db = None if expirey == 0 else expirey
|
||||
client = Client(
|
||||
id=client_id,
|
||||
secret=client_secret,
|
||||
expirey=expirey_db,
|
||||
application_type=data["type"]
|
||||
)
|
||||
client.save()
|
||||
|
||||
elif request.method == "PUT":
|
||||
# updating client
|
||||
pass
|
||||
return json_response(
|
||||
{
|
||||
"client_id":client_id,
|
||||
"client_secret":client_secret,
|
||||
"expires_at":expirey,
|
||||
})
|
||||
|
@ -36,6 +36,7 @@ def get_url_map():
|
||||
import mediagoblin.webfinger.routing
|
||||
import mediagoblin.listings.routing
|
||||
import mediagoblin.notifications.routing
|
||||
import mediagoblin.federation.routing
|
||||
|
||||
for route in PluginManager().get_routes():
|
||||
add_route(*route)
|
||||
|
@ -14,6 +14,8 @@
|
||||
# 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 base64
|
||||
import string
|
||||
import errno
|
||||
import itsdangerous
|
||||
import logging
|
||||
@ -24,6 +26,9 @@ from mediagoblin import mg_globals
|
||||
|
||||
_log = logging.getLogger(__name__)
|
||||
|
||||
# produces base64 alphabet
|
||||
alphabet = string.ascii_letters + "-_"
|
||||
base = len(alphabet)
|
||||
|
||||
# Use the system (hardware-based) random number generator if it exists.
|
||||
# -- this optimization is lifted from Django
|
||||
@ -111,3 +116,13 @@ def get_timed_signer_url(namespace):
|
||||
assert __itsda_secret is not None
|
||||
return itsdangerous.URLSafeTimedSerializer(__itsda_secret,
|
||||
salt=namespace)
|
||||
|
||||
def random_string(length):
|
||||
""" Returns a URL safe base64 encoded crypographically strong string """
|
||||
rstring = ""
|
||||
for i in range(length):
|
||||
n = getrandbits(6) # 6 bytes = 2^6 = 64
|
||||
n = divmod(n, base)[1]
|
||||
rstring += alphabet[n]
|
||||
|
||||
return rstring
|
||||
|
@ -1,41 +0,0 @@
|
||||
# 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 json
|
||||
|
||||
from werkzeug.wrappers import Response
|
||||
|
||||
def json_response(serializable, _disable_cors=False, *args, **kw):
|
||||
'''
|
||||
Serializes a json objects and returns a werkzeug Response object with the
|
||||
serialized value as the response body and Content-Type: application/json.
|
||||
|
||||
:param serializable: A json-serializable object
|
||||
|
||||
Any extra arguments and keyword arguments are passed to the
|
||||
Response.__init__ method.
|
||||
'''
|
||||
response = Response(json.dumps(serializable), *args, content_type='application/json', **kw)
|
||||
|
||||
if not _disable_cors:
|
||||
cors_headers = {
|
||||
'Access-Control-Allow-Origin': '*',
|
||||
'Access-Control-Allow-Methods': 'POST, GET, OPTIONS',
|
||||
'Access-Control-Allow-Headers': 'Content-Type, X-Requested-With'}
|
||||
for key, value in cors_headers.iteritems():
|
||||
response.headers.set(key, value)
|
||||
|
||||
return response
|
@ -14,6 +14,8 @@
|
||||
# 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 json
|
||||
|
||||
import werkzeug.utils
|
||||
from werkzeug.wrappers import Response as wz_Response
|
||||
from mediagoblin.tools.template import render_template
|
||||
@ -31,7 +33,6 @@ def render_to_response(request, template, context, status=200):
|
||||
render_template(request, template, context),
|
||||
status=status)
|
||||
|
||||
|
||||
def render_error(request, status=500, title=_('Oops!'),
|
||||
err_msg=_('An error occured')):
|
||||
"""Render any error page with a given error code, title and text body
|
||||
@ -44,7 +45,6 @@ def render_error(request, status=500, title=_('Oops!'),
|
||||
{'err_code': status, 'title': title, 'err_msg': err_msg}),
|
||||
status=status)
|
||||
|
||||
|
||||
def render_403(request):
|
||||
"""Render a standard 403 page"""
|
||||
_ = pass_to_ugettext
|
||||
@ -106,3 +106,26 @@ def redirect_obj(request, obj):
|
||||
|
||||
Requires obj to have a .url_for_self method."""
|
||||
return redirect(request, location=obj.url_for_self(request.urlgen))
|
||||
|
||||
def json_response(serializable, _disable_cors=False, *args, **kw):
|
||||
'''
|
||||
Serializes a json objects and returns a werkzeug Response object with the
|
||||
serialized value as the response body and Content-Type: application/json.
|
||||
|
||||
:param serializable: A json-serializable object
|
||||
|
||||
Any extra arguments and keyword arguments are passed to the
|
||||
Response.__init__ method.
|
||||
'''
|
||||
|
||||
response = wz_Response(json.dumps(serializable), *args, content_type='application/json', **kw)
|
||||
|
||||
if not _disable_cors:
|
||||
cors_headers = {
|
||||
'Access-Control-Allow-Origin': '*',
|
||||
'Access-Control-Allow-Methods': 'POST, GET, OPTIONS',
|
||||
'Access-Control-Allow-Headers': 'Content-Type, X-Requested-With'}
|
||||
for key, value in cors_headers.iteritems():
|
||||
response.headers.set(key, value)
|
||||
|
||||
return response
|
||||
|
Loading…
x
Reference in New Issue
Block a user