Skip to content
GitLab
Menu
Projects
Groups
Snippets
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
Menu
Open sidebar
retribute.me
api
Commits
4f83d1bb
Verified
Commit
4f83d1bb
authored
May 28, 2019
by
Eliot Berriot
Browse files
Added API endpoint to query profiles
parent
8203fa01
Changes
6
Hide whitespace changes
Inline
Side-by-side
config/routing.py
0 → 100644
View file @
4f83d1bb
from
django.conf.urls
import
url
from
channels.routing
import
ProtocolTypeRouter
,
URLRouter
from
retribute_api.search
import
consumers
application
=
ProtocolTypeRouter
(
{
"http"
:
URLRouter
(
[
url
(
r
"^api/v1/search/(?P<lookup_type>.+):(?P<lookup>.+)$"
,
consumers
.
SearchSingleConsumer
,
)
]
)
}
)
retribute_api/search/consumers.py
0 → 100644
View file @
4f83d1bb
import
aiohttp.client
import
json
from
channels.generic.http
import
AsyncHttpConsumer
from
.
import
sources
async
def
json_response
(
self
,
status
,
content
):
await
self
.
send_response
(
status
,
json
.
dumps
(
content
,
indent
=
2
,
sort_keys
=
True
).
encode
(
"utf-8"
),
headers
=
[{
"Content-Type"
:
"application/json"
}],
)
class
SearchSingleConsumer
(
AsyncHttpConsumer
):
async
def
handle
(
self
,
body
):
lookup_type
=
self
.
scope
[
"url_route"
][
"kwargs"
][
"lookup_type"
]
lookup
=
self
.
scope
[
"url_route"
][
"kwargs"
][
"lookup"
]
try
:
source
=
sources
.
registry
.
_data
[
lookup_type
]
except
KeyError
:
await
json_response
(
self
,
400
,
{
"detail"
:
"Invalid lookup"
})
try
:
async
with
aiohttp
.
client
.
ClientSession
()
as
session
:
data
=
await
source
.
get
(
lookup
,
session
)
except
Exception
:
raise
try
:
profile
=
sources
.
result_to_retribute_profile
(
lookup_type
,
lookup
,
data
)
except
Exception
:
raise
await
json_response
(
self
,
200
,
profile
)
retribute_api/search/sources.py
View file @
4f83d1bb
...
...
@@ -34,11 +34,11 @@ class Activitypub(Source):
id
=
"activitypub"
async
def
get
(
self
,
lookup
,
session
):
response
=
awa
it
session
.
get
(
async
w
it
h
session
.
get
(
lookup
,
headers
=
{
"Accept"
:
"application/activity+json"
}
)
response
.
raise_for_status
()
actor_data
=
await
response
.
json
()
)
as
response
:
response
.
raise_for_status
()
actor_data
=
await
response
.
json
()
serializer
=
activitypub
.
ActorSerializer
(
data
=
actor_data
)
serializer
.
is_valid
(
raise_exception
=
True
)
for
tag
in
serializer
.
validated_data
[
"tag"
]:
...
...
@@ -64,12 +64,11 @@ class Webfinger(Source):
found
=
None
if
"activitypub"
in
links
:
found
=
await
Activitypub
().
get
(
links
[
"activitypub"
],
session
)
return
found
def
result_to_retribute_profile
(
lookup_type
,
lookup
,
data
):
path
=
settings
.
BASE_URL
+
"/compat
/
"
path
=
settings
.
BASE_URL
+
"/compat"
now
=
timezone
.
now
()
valid_means
=
[
(
link
,
means
.
extract_from_url
(
link
[
"url"
]))
for
link
in
data
[
"links"
]
...
...
@@ -89,7 +88,7 @@ def result_to_retribute_profile(lookup_type, lookup, data):
final
=
{
"version"
:
"0.1"
,
"id"
:
"
https://retribute.me.test/compat
/{}:{}"
.
format
(
lookup_type
,
lookup
),
"id"
:
"
{}
/{}:{}"
.
format
(
path
,
lookup_type
,
lookup
),
"title"
:
"Compat profile for {}:{}"
.
format
(
lookup_type
,
lookup
),
"updated"
:
now
.
isoformat
(),
"identities"
:
[],
...
...
retribute_api/search/webfinger.py
View file @
4f83d1bb
...
...
@@ -3,12 +3,12 @@ from rest_framework import serializers
async
def
lookup
(
name
,
session
):
username
,
domain
=
name
.
split
(
"@"
)
response
=
awa
it
session
.
get
(
async
w
it
h
session
.
get
(
"https://{}/.well-known/webfinger"
.
format
(
domain
),
params
=
{
"resource"
:
"acct:{}"
.
format
(
name
)},
)
response
.
raise_for_status
()
return
await
response
.
json
()
)
as
response
:
response
.
raise_for_status
()
return
await
response
.
json
()
class
AccountLinkSerializer
(
serializers
.
Serializer
):
...
...
tests/conftest.py
View file @
4f83d1bb
...
...
@@ -5,6 +5,7 @@ import asynctest
from
django.utils
import
timezone
from
config
import
routing
pytest_plugins
=
"aiohttp.pytest_plugin"
...
...
@@ -31,3 +32,8 @@ def now(mocker):
now
=
timezone
.
now
()
mocker
.
patch
.
object
(
timezone
,
"now"
,
return_value
=
now
)
return
now
@
pytest
.
fixture
def
application
():
return
routing
.
application
tests/search/test_consumers.py
0 → 100644
View file @
4f83d1bb
import
json
from
channels.testing
import
HttpCommunicator
from
retribute_api.search
import
consumers
from
retribute_api.search
import
sources
async
def
test_search_consumer_success
(
loop
,
application
,
mocker
,
coroutine_mock
):
get
=
mocker
.
patch
.
object
(
sources
.
Webfinger
,
"get"
,
coroutine_mock
())
expected
=
{
"dummy"
:
"json"
}
get_profile
=
mocker
.
patch
.
object
(
sources
,
"result_to_retribute_profile"
,
return_value
=
expected
)
communicator
=
HttpCommunicator
(
application
,
"GET"
,
"/api/v1/search/webfinger:test@user.domain"
)
response
=
await
communicator
.
get_response
()
assert
get
.
call_args
[
0
][
0
]
==
"test@user.domain"
get_profile
.
assert_called_once_with
(
"webfinger"
,
"test@user.domain"
,
get
.
return_value
)
assert
response
[
"status"
]
==
200
assert
response
[
"headers"
]
==
[{
"Content-Type"
:
"application/json"
}]
assert
response
[
"body"
]
==
json
.
dumps
(
expected
,
indent
=
2
,
sort_keys
=
True
).
encode
()
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
.
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment