137 lines
4.8 KiB
Python
137 lines
4.8 KiB
Python
from hashlib import md5
|
|
|
|
from django.contrib.auth.models import User
|
|
from django.test import RequestFactory
|
|
from django.urls import reverse
|
|
from django.utils.http import urlencode
|
|
|
|
from allauth import app_settings
|
|
from allauth.socialaccount.models import SocialApp, SocialToken
|
|
from allauth.tests import Mock, TestCase, patch
|
|
|
|
from . import views
|
|
from .provider import DraugiemProvider
|
|
|
|
|
|
class DraugiemTests(TestCase):
|
|
def setUp(self):
|
|
# workaround to create a session. see:
|
|
# https://code.djangoproject.com/ticket/11475
|
|
User.objects.create_user(
|
|
"anakin", "skywalker@deathstar.example.com", "s1thrul3s"
|
|
)
|
|
self.client.login(username="anakin", password="s1thrul3s")
|
|
|
|
app = SocialApp.objects.create(
|
|
provider=DraugiemProvider.id,
|
|
name=DraugiemProvider.id,
|
|
client_id="app123id",
|
|
key=DraugiemProvider.id,
|
|
secret="dummy",
|
|
)
|
|
request = RequestFactory().get("/")
|
|
self.provider = app.get_provider(request)
|
|
if app_settings.SITES_ENABLED:
|
|
from django.contrib.sites.models import Site
|
|
|
|
app.sites.add(Site.objects.get_current())
|
|
self.app = app
|
|
|
|
def get_draugiem_login_response(self):
|
|
"""
|
|
Sample Draugiem.lv response
|
|
"""
|
|
return {
|
|
"apikey": "12345",
|
|
"uid": "42",
|
|
"users": {
|
|
"42": {
|
|
"age": "266",
|
|
"imgl": "http://cdn.memegenerator.net/instances/500x/23395689.jpg",
|
|
"surname": "Skywalker",
|
|
"url": "/user/42/",
|
|
"imgi": "http://cdn.memegenerator.net/instances/500x/23395689.jpg",
|
|
"nick": "Sky Guy",
|
|
"created": "09.11.1812 11:26:15",
|
|
"deleted": "false",
|
|
"imgm": "http://cdn.memegenerator.net/instances/500x/23395689.jpg",
|
|
"sex": "M",
|
|
"type": "User_Default",
|
|
"uid": "42",
|
|
"place": "London",
|
|
"emailHash": "3f198f21434gfd2f2b4rs05939shk93f3815bc6aa",
|
|
"name": "Anakin",
|
|
"adult": "1",
|
|
"birthday": "1750-09-13",
|
|
"img": "http://cdn.memegenerator.net/instances/500x/23395689.jpg",
|
|
}
|
|
},
|
|
}
|
|
|
|
def get_socialaccount(self, response, token):
|
|
"""
|
|
Returns SocialLogin based on the data from the request
|
|
"""
|
|
request = Mock()
|
|
login = self.provider.sociallogin_from_response(request, response)
|
|
login.token = token
|
|
return login
|
|
|
|
def mock_socialaccount_state(self):
|
|
"""
|
|
SocialLogin depends on Session state - a tuple of request
|
|
params and a random string
|
|
"""
|
|
session = self.client.session
|
|
session["socialaccount_state"] = (
|
|
{"process": "login", "scope": "", "auth_params": ""},
|
|
"12345",
|
|
)
|
|
session.save()
|
|
|
|
def test_login_redirect(self):
|
|
response = self.client.get(reverse(views.login))
|
|
redirect_url = reverse(views.callback)
|
|
full_redirect_url = "http://testserver" + redirect_url
|
|
secret = self.app.secret + full_redirect_url
|
|
redirect_url_hash = md5(secret.encode("utf-8")).hexdigest()
|
|
params = {
|
|
"app": self.app.client_id,
|
|
"hash": redirect_url_hash,
|
|
"redirect": full_redirect_url,
|
|
}
|
|
self.assertRedirects(
|
|
response,
|
|
"%s?%s" % (views.AUTHORIZE_URL, urlencode(params)),
|
|
fetch_redirect_response=False,
|
|
)
|
|
|
|
def test_callback_no_auth_status(self):
|
|
response = self.client.get(reverse(views.callback))
|
|
self.assertTemplateUsed(response, "socialaccount/authentication_error.html")
|
|
|
|
def test_callback_invalid_auth_status(self):
|
|
response = self.client.get(reverse(views.callback), {"dr_auth_status": "fail"})
|
|
self.assertTemplateUsed(response, "socialaccount/authentication_error.html")
|
|
|
|
def test_callback(self):
|
|
with patch(
|
|
"allauth.socialaccount.providers.draugiem.views.draugiem_complete_login"
|
|
) as draugiem_complete_login:
|
|
self.mock_socialaccount_state()
|
|
|
|
response_json = self.get_draugiem_login_response()
|
|
|
|
token = SocialToken(app=self.app, token=response_json["apikey"])
|
|
login = self.get_socialaccount(response_json, token)
|
|
|
|
draugiem_complete_login.return_value = login
|
|
|
|
response = self.client.get(
|
|
reverse(views.callback),
|
|
{"dr_auth_status": "ok", "dr_auth_code": "42"},
|
|
)
|
|
self.assertRedirects(
|
|
response, "/accounts/profile/", fetch_redirect_response=False
|
|
)
|