Skip to content

Commit

Permalink
feat(providers): add nextcloud
Browse files Browse the repository at this point in the history
  • Loading branch information
Guilhem Saurel authored and pennersr committed Apr 26, 2019
1 parent 01bde6b commit 9adad2c
Show file tree
Hide file tree
Showing 11 changed files with 157 additions and 0 deletions.
1 change: 1 addition & 0 deletions AUTHORS
Expand Up @@ -45,6 +45,7 @@ Fred Palmer
Fábio Santos
George Whewell
Griffith Rees
Guilhem Saurel
Guillaume Vincent
Guoyu Hao
Hatem Nassrat
Expand Down
1 change: 1 addition & 0 deletions ChangeLog.rst
Expand Up @@ -5,6 +5,7 @@ Note worthy changes
-------------------

- The ``instagram`` provider now extracts the user's full name.
- New provider: NextCloud (OAuth2)


0.39.1 (2019-02-28)
Expand Down
Empty file.
28 changes: 28 additions & 0 deletions allauth/socialaccount/providers/nextcloud/provider.py
@@ -0,0 +1,28 @@
from allauth.socialaccount.providers.base import ProviderAccount
from allauth.socialaccount.providers.oauth2.provider import OAuth2Provider


class NextCloudAccount(ProviderAccount):
pass


class NextCloudProvider(OAuth2Provider):
id = 'nextcloud'
name = 'NextCloud'
account_class = NextCloudAccount

def extract_uid(self, data):
return str(data['id'])

def extract_common_fields(self, data):
return dict(
username=data['displayname'],
email=data['email'],
)

def get_default_scope(self):
scope = ['read']
return scope


provider_classes = [NextCloudProvider]
63 changes: 63 additions & 0 deletions allauth/socialaccount/providers/nextcloud/tests.py
@@ -0,0 +1,63 @@
from django.test.utils import override_settings

from allauth.socialaccount.tests import OAuth2TestsMixin
from allauth.tests import MockedResponse, TestCase

from .provider import NextCloudProvider


@override_settings(SOCIALACCOUNT_PROVIDERS={
'nextcloud': {
'SERVER': 'https://nextcloud.example.org'
}
})
class NextCloudTests(OAuth2TestsMixin, TestCase):
provider_id = NextCloudProvider.id

def get_login_response_json(self, with_refresh_token=True):
return super(NextCloudTests, self).get_login_response_json(
with_refresh_token=with_refresh_token).replace('uid', 'user_id')

def get_mocked_response(self):
return MockedResponse(
200, """<?xml version="1.0"?>
<ocs>
<meta>
<status>ok</status>
<statuscode>100</statuscode>
<message>OK</message>
<totalitems></totalitems>
<itemsperpage></itemsperpage>
</meta>
<data>
<enabled>1</enabled>
<id>batman</id>
<storageLocation>/var/www/html/data/batman</storageLocation>
<lastLogin>1553946472000</lastLogin>
<backend>Database</backend>
<subadmin/>
<quota>
<free>1455417655296</free>
<used>467191265</used>
<total>1455884846561</total>
<relative>0.03</relative>
<quota>-3</quota>
</quota>
<email>batman@wayne.com</email>
<displayname>batman</displayname>
<phone>7351857301</phone>
<address>BatCave, Gotham City</address>
<website>https://batman.org</website>
<twitter>@the_batman</twitter>
<groups>
<element>admin</element>
</groups>
<language>fr</language>
<locale>fr_FR</locale>
<backendCapabilities>
<setDisplayName>1</setDisplayName>
<setPassword>1</setPassword>
</backendCapabilities>
</data>
</ocs>
""")
6 changes: 6 additions & 0 deletions allauth/socialaccount/providers/nextcloud/urls.py
@@ -0,0 +1,6 @@
from allauth.socialaccount.providers.oauth2.urls import default_urlpatterns

from .provider import NextCloudProvider


urlpatterns = default_urlpatterns(NextCloudProvider)
36 changes: 36 additions & 0 deletions allauth/socialaccount/providers/nextcloud/views.py
@@ -0,0 +1,36 @@
import requests
import xml.etree.ElementTree as ET

from allauth.socialaccount import app_settings
from allauth.socialaccount.providers.oauth2.views import (
OAuth2Adapter,
OAuth2CallbackView,
OAuth2LoginView,
)

from .provider import NextCloudProvider


class NextCloudAdapter(OAuth2Adapter):
provider_id = NextCloudProvider.id
settings = app_settings.PROVIDERS.get(provider_id, {})
server = settings.get('SERVER', 'https://nextcloud.example.org')
access_token_url = '{0}/apps/oauth2/api/v1/token'.format(server)
authorize_url = '{0}/apps/oauth2/authorize'.format(server)
profile_url = '{0}/ocs/v1.php/cloud/users/'.format(server)

def complete_login(self, request, app, token, **kwargs):
extra_data = self.get_user_info(token, kwargs['response']['user_id'])
return self.get_provider().sociallogin_from_response(
request, extra_data)

def get_user_info(self, token, user_id):
headers = {'Authorization': 'Bearer {0}'.format(self.server)}
resp = requests.get(self.profile_url + user_id, headers=headers)
resp.raise_for_status()
data = ET.fromstring(resp.content.decode())[1]
return {d.tag: d.text.strip() for d in data if d.text is not None}


oauth2_login = OAuth2LoginView.adapter_view(NextCloudAdapter)
oauth2_callback = OAuth2CallbackView.adapter_view(NextCloudAdapter)
1 change: 1 addition & 0 deletions docs/installation.rst
Expand Up @@ -94,6 +94,7 @@ settings.py (Important - Please note 'django.contrib.sites' is required as INSTA
'allauth.socialaccount.providers.meetup',
'allauth.socialaccount.providers.microsoft',
'allauth.socialaccount.providers.naver',
'allauth.socialaccount.providers.nextcloud',
'allauth.socialaccount.providers.odnoklassniki',
'allauth.socialaccount.providers.openid',
'allauth.socialaccount.providers.orcid',
Expand Down
2 changes: 2 additions & 0 deletions docs/overview.rst
Expand Up @@ -123,6 +123,8 @@ Supported Providers

- Microsoft (Graph) (OAuth2)

- NextCloud (OAuth2)

- Naver (OAuth2)

- Odnoklassniki (OAuth2)
Expand Down
18 changes: 18 additions & 0 deletions docs/providers.rst
Expand Up @@ -960,6 +960,24 @@ Development callback URL
http://localhost:8000/accounts/naver/login/callback/


NextCloud
---------

The following NextCloud settings are available:

.. code-block:: python
SOCIALACCOUNT_PROVIDERS = {
'nextcloud': {
'SERVER': 'https://nextcloud.example.org',
}
}
App registration (get your key and secret here)

https://nextcloud.example.org/settings/admin/security

Odnoklassniki
-------------

Expand Down
1 change: 1 addition & 0 deletions test_settings.py
Expand Up @@ -102,6 +102,7 @@
'allauth.socialaccount.providers.meetup',
'allauth.socialaccount.providers.microsoft',
'allauth.socialaccount.providers.naver',
'allauth.socialaccount.providers.nextcloud',
'allauth.socialaccount.providers.odnoklassniki',
'allauth.socialaccount.providers.openid',
'allauth.socialaccount.providers.orcid',
Expand Down

0 comments on commit 9adad2c

Please sign in to comment.