diff --git a/mediagoblin/db/models.py b/mediagoblin/db/models.py
index b96129ae..61a7f251 100644
--- a/mediagoblin/db/models.py
+++ b/mediagoblin/db/models.py
@@ -138,13 +138,37 @@ class User(Base, UserMixin):
def serialize(self, request):
user = {
+ "id": "acct:{0}@{1}".format(self.username, request.url),
"preferredUsername": self.username,
- "displayName": "{username}@{server}".format(username=self.username, server=request.url)
+ "displayName": "{0}@{1}".format(self.username, request.url),
"objectType": "person",
"url": self.url,
+ "summary": self.bio,
"links": {
+ "self": {
+ "href": request.urlgen(
+ "mediagoblin.federation.profile",
+ username=self.username,
+ qualified=True
+ ),
+ },
+ "activity-inbox": {
+ "href": request.urlgen(
+ "mediagoblin.federation.inbox",
+ username=self.username,
+ qualified=True
+ )
+ },
+ "activity-outbox": {
+ "href": request.urlgen(
+ "mediagoblin.federation.feed",
+ username=self.username,
+ qualified=True
+ )
+ },
},
}
+ return user
class Client(Base):
"""
diff --git a/mediagoblin/decorators.py b/mediagoblin/decorators.py
index 8515d091..040a11fa 100644
--- a/mediagoblin/decorators.py
+++ b/mediagoblin/decorators.py
@@ -401,7 +401,7 @@ def oauth_required(controller):
request_validator = GMGRequestValidator()
resource_endpoint = ResourceEndpoint(request_validator)
- valid, request = resource_endpoint.validate_protected_resource_request(
+ valid, r = resource_endpoint.validate_protected_resource_request(
uri=request.url,
http_method=request.method,
body=request.get_data(),
diff --git a/mediagoblin/federation/__init__.py b/mediagoblin/federation/__init__.py
new file mode 100644
index 00000000..e69de29b
diff --git a/mediagoblin/federation/routing.py b/mediagoblin/federation/routing.py
new file mode 100644
index 00000000..9c3e0dff
--- /dev/null
+++ b/mediagoblin/federation/routing.py
@@ -0,0 +1,43 @@
+# 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 .
+
+from mediagoblin.tools.routing import add_route
+
+# Add user profile
+add_route(
+ "mediagoblin.federation.user",
+ "/api/user//",
+ "mediagoblin.federation.views:user"
+ )
+
+add_route(
+ "mediagoblin.federation.profile",
+ "/api/user//profile",
+ "mediagoblin.federation.views:user"
+ )
+
+# Inbox and Outbox (feed)
+add_route(
+ "mediagoblin.federation.feed",
+ "/api/user//feed",
+ "mediagoblin.federation.views:feed"
+ )
+
+add_route(
+ "mediagoblin.federation.inbox",
+ "/api/user//inbox",
+ "mediagoblin.federation.views:inbox"
+ )
diff --git a/mediagoblin/federation/views.py b/mediagoblin/federation/views.py
new file mode 100644
index 00000000..337f28ed
--- /dev/null
+++ b/mediagoblin/federation/views.py
@@ -0,0 +1,42 @@
+from mediagoblin.decorators import oauth_required
+from mediagoblin.db.models import User
+from mediagoblin.tools.response import json_response
+
+@oauth_required
+def user(request):
+ """ Handles user response at /api/user// """
+ user = request.matchdict["username"]
+ requested_user = User.query.filter_by(username=user)
+
+ # check if the user exists
+ if requested_user is None:
+ error = "No such 'user' with id '{0}'".format(user)
+ return json_response({"error": error}, status=404)
+
+ user = requested_user[0]
+
+ # user profiles are public so return information
+ return json_response(user.serialize(request))
+
+@oauth_required
+def feed(request):
+ """ Handles the user's outbox - /api/user//feed """
+ user = request.matchdict["username"]
+ requested_user = User.query.filter_by(username=user)
+
+ # check if the user exists
+ if requested_user is None:
+ error = "No such 'user' with id '{0}'".format(user)
+ return json_response({"error": error}, status=404)
+
+ user = request_user[0]
+
+ # Now lookup the user's feed.
+ raise NotImplemented("Yet to implement looking up user's feed")
+
+@oauth_required
+def inbox(request):
+ """ Handles the user's inbox - /api/user//inbox """
+ pass
+
+ raise NotImplemented("Yet to implement looking up user's inbox")