Skip to content

Commit

Permalink
feat(providers): Add gitea as provider
Browse files Browse the repository at this point in the history
Signed-off-by: techknowlogick <techknowlogick@gitea.io>
  • Loading branch information
techknowlogick committed Aug 20, 2021
1 parent cc0dfb7 commit 60cf9a4
Show file tree
Hide file tree
Showing 9 changed files with 165 additions and 0 deletions.
Empty file.
45 changes: 45 additions & 0 deletions allauth/socialaccount/providers/gitea/provider.py
@@ -0,0 +1,45 @@
from allauth.socialaccount.providers.base import ProviderAccount
from allauth.socialaccount.providers.oauth2.provider import OAuth2Provider


class GiteaAccount(ProviderAccount):
def get_profile_url(self):
return self.account.extra_data.get("html_url")

def get_avatar_url(self):
return self.account.extra_data.get("avatar_url")

def to_str(self):
dflt = super(GiteaAccount, self).to_str()
return next(
value
for value in (
self.account.extra_data.get("username", None),
self.account.extra_data.get("login", None),
dflt,
)
if value is not None
)


class GiteaProvider(OAuth2Provider):
id = "gitea"
name = "Gitea"
account_class = GiteaAccount

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

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

def extract_common_fields(self, data):
return dict(
email=data.get("email"),
username=data.get("login"),
name=data.get("name"),
)


provider_classes = [GiteaProvider]
51 changes: 51 additions & 0 deletions allauth/socialaccount/providers/gitea/tests.py
@@ -0,0 +1,51 @@
from allauth.socialaccount.models import SocialAccount
from allauth.socialaccount.tests import OAuth2TestsMixin
from allauth.tests import MockedResponse, TestCase

from .provider import GiteaProvider


class GiteaTests(OAuth2TestsMixin, TestCase):
provider_id = GiteaProvider.id

def get_mocked_response(self):
return MockedResponse(
200,
"""
{
"id": 4940,
"login": "giteauser",
"full_name": "",
"email": "giteauser@example.com",
"avatar_url": "https://gitea.com/user/avatar/giteauser/-1",
"language": "en-US",
"is_admin": true,
"last_login": "2021-08-20T20:07:39Z",
"created": "2018-05-03T16:04:34Z",
"restricted": false,
"active": true,
"prohibit_login": false,
"location": "",
"website": "",
"description": "",
"visibility": "public",
"followers_count": 0,
"following_count": 0,
"starred_repos_count": 0,
"username": "giteauser"
}""",
)

def test_account_name_null(self):
"""String conversion when Gitea responds with empty username"""
data = """{
"id": 4940,
"login": "giteauser",
"username": null
}"""
self.login(MockedResponse(200, data))
socialaccount = SocialAccount.objects.get(uid="4940")
self.assertIsNone(socialaccount.extra_data.get("name"))
account = socialaccount.get_provider_account()
self.assertIsNotNone(account.to_str())
self.assertEqual(account.to_str(), "giteauser")
6 changes: 6 additions & 0 deletions allauth/socialaccount/providers/gitea/urls.py
@@ -0,0 +1,6 @@
from allauth.socialaccount.providers.oauth2.urls import default_urlpatterns

from .provider import GiteaProvider


urlpatterns = default_urlpatterns(GiteaProvider)
36 changes: 36 additions & 0 deletions allauth/socialaccount/providers/gitea/views.py
@@ -0,0 +1,36 @@
import requests

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


class GiteaOAuth2Adapter(OAuth2Adapter):
provider_id = GiteaProvider.id
settings = app_settings.PROVIDERS.get(provider_id, {})

if "GITEA_URL" in settings:
web_url = settings.get("GITEA_URL").rstrip("/")
api_url = "{0}/api/v1".format(web_url)
else:
web_url = "https://gitea.com"
api_url = "https://gitea.com"

access_token_url = "{0}/login/oauth/access_token".format(web_url)
authorize_url = "{0}/login/oauth/authorize".format(web_url)
profile_url = "{0}/user".format(api_url)

def complete_login(self, request, app, token, **kwargs):
headers = {"Authorization": "token {}".format(token.token)}
resp = requests.get(self.profile_url, headers=headers)
resp.raise_for_status()
extra_data = resp.json()
return self.get_provider().sociallogin_from_response(request, extra_data)


oauth2_login = OAuth2LoginView.adapter_view(GiteaOAuth2Adapter)
oauth2_callback = OAuth2CallbackView.adapter_view(GiteaOAuth2Adapter)
1 change: 1 addition & 0 deletions docs/installation.rst
Expand Up @@ -91,6 +91,7 @@ settings.py (Important - Please note 'django.contrib.sites' is required as INSTA
'allauth.socialaccount.providers.foursquare',
'allauth.socialaccount.providers.frontier',
'allauth.socialaccount.providers.fxa',
'allauth.socialaccount.providers.gitea',
'allauth.socialaccount.providers.github',
'allauth.socialaccount.providers.gitlab',
'allauth.socialaccount.providers.globus',
Expand Down
2 changes: 2 additions & 0 deletions docs/overview.rst
Expand Up @@ -119,6 +119,8 @@ Supported Providers

- Frontier (OAuth2)

- Gitea (OAuth2)

- Github (OAuth2)

- GitLab (OAuth2)
Expand Down
23 changes: 23 additions & 0 deletions docs/providers.rst
Expand Up @@ -807,6 +807,29 @@ Optionally, you can specify the scope to use as follows:
},
}
Gitea
------

App registration (get your key and secret here)
https://gitea.com/user/settings/applications

Development callback URL
http://127.0.0.1:8000/accounts/github/login/callback/


Self-hosted Support
******************

If you use a self-hosted Gitea instance add your server URL to your Django settings as
follows:

.. code-block:: python
SOCIALACCOUNT_PROVIDERS = {
'gitea': {
'GITEA_URL': 'https://your.gitea-server.domain',
}
}
GitHub
------
Expand Down
1 change: 1 addition & 0 deletions test_settings.py
Expand Up @@ -93,6 +93,7 @@
"allauth.socialaccount.providers.foursquare",
"allauth.socialaccount.providers.frontier",
"allauth.socialaccount.providers.fxa",
"allauth.socialaccount.providers.gitea",
"allauth.socialaccount.providers.github",
"allauth.socialaccount.providers.gitlab",
"allauth.socialaccount.providers.globus",
Expand Down

0 comments on commit 60cf9a4

Please sign in to comment.