Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Migrate GitHub OAuth App to GitHub App #11942

Draft
wants to merge 3 commits into
base: main
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Empty file.
10 changes: 10 additions & 0 deletions readthedocs/allauth/providers/githubapp/provider.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
from allauth.socialaccount.providers.github.provider import GitHubProvider
from readthedocs.allauth.providers.githubapp.views import GitHubAppOAuth2Adapter


class GitHubAppProvider(GitHubProvider):
id = "githubapp"
name = "GitHub App"
oauth2_adapter_class = GitHubAppOAuth2Adapter

provider_classes = [GitHubAppProvider]
6 changes: 6 additions & 0 deletions readthedocs/allauth/providers/githubapp/urls.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
from allauth.socialaccount.providers.oauth2.urls import default_urlpatterns

from readthedocs.allauth.providers.githubapp.provider import GitHubAppProvider


urlpatterns = default_urlpatterns(GitHubAppProvider)
13 changes: 13 additions & 0 deletions readthedocs/allauth/providers/githubapp/views.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
from allauth.socialaccount.providers.github.views import GitHubOAuth2Adapter

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

class GitHubAppOAuth2Adapter(GitHubOAuth2Adapter):
provider_id = 'githubapp'


oauth2_login = OAuth2LoginView.adapter_view(GitHubAppOAuth2Adapter)
oauth2_callback = OAuth2CallbackView.adapter_view(GitHubAppOAuth2Adapter)
18 changes: 18 additions & 0 deletions readthedocs/core/adapters.py
Original file line number Diff line number Diff line change
@@ -1,9 +1,14 @@
"""Allauth overrides."""

from allauth.socialaccount.adapter import DefaultSocialAccountAdapter
from allauth.socialaccount.models import SocialAccount
from allauth.socialaccount.providers.github.provider import GitHubProvider

import structlog
from allauth.account.adapter import DefaultAccountAdapter
from django.utils.encoding import force_str

from readthedocs.allauth.providers.githubapp.provider import GitHubAppProvider
from readthedocs.core.utils import send_email_from_object
from readthedocs.invitations.models import Invitation

Expand Down Expand Up @@ -50,3 +55,16 @@ def save_user(self, request, user, form, commit=True):
invitation.delete()
else:
log.info("Invitation not found", invitation_pk=invitation_pk)


class SocialAccountAdapter(DefaultSocialAccountAdapter):

def pre_social_login(self, request, sociallogin):
provider = sociallogin.account.get_provider()
if provider.id == GitHubAppProvider.id and not sociallogin.is_existing:
stsewd marked this conversation as resolved.
Show resolved Hide resolved
social_ccount = SocialAccount.objects.filter(
stsewd marked this conversation as resolved.
Show resolved Hide resolved
provider=GitHubProvider.id,
uid=sociallogin.account.uid,
).first()
if social_ccount:
sociallogin.connect(request, social_ccount.user)
20 changes: 13 additions & 7 deletions readthedocs/settings/base.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,19 +2,17 @@

import os
import re
import subprocess
import socket
import subprocess

import structlog

from celery.schedules import crontab
from corsheaders.defaults import default_headers
from django.conf.global_settings import PASSWORD_HASHERS

from readthedocs.builds import constants_docker
from readthedocs.core.logs import shared_processors
from corsheaders.defaults import default_headers
from readthedocs.core.settings import Settings
from readthedocs.builds import constants_docker

from django.conf.global_settings import PASSWORD_HASHERS

try:
import readthedocsext.cdn # noqa
Expand Down Expand Up @@ -73,7 +71,7 @@ def _show_debug_toolbar(request):
# It's a "known issue/bug" and there is no solution as far as we can tell.
"debug_toolbar.panels.sql.SQLPanel",
"debug_toolbar.panels.templates.TemplatesPanel",
]
],
}

@property
Expand Down Expand Up @@ -294,6 +292,7 @@ def INSTALLED_APPS(self): # noqa
"allauth.account",
"allauth.socialaccount",
"allauth.socialaccount.providers.github",
"readthedocs.allauth.providers.githubapp",
"allauth.socialaccount.providers.gitlab",
"allauth.socialaccount.providers.bitbucket_oauth2",
"allauth.mfa",
Expand Down Expand Up @@ -679,6 +678,7 @@ def DOCKER_LIMITS(self):

# Allauth
ACCOUNT_ADAPTER = "readthedocs.core.adapters.AccountAdapter"
SOCIALACCOUNT_ADAPTER = 'readthedocs.core.adapters.SocialAccountAdapter'
ACCOUNT_EMAIL_REQUIRED = True
# By preventing enumeration, we will always send an email,
# even if the email is not registered, that's hurting
Expand Down Expand Up @@ -709,6 +709,12 @@ def DOCKER_LIMITS(self):
"repo:status",
],
},
"githubapp": {
"APPS": [
{"client_id": "123", "secret": "456", "key": ""},
],
"SCOPE": [],
},
"gitlab": {
"APPS": [
{"client_id": "123", "secret": "456", "key": ""},
Expand Down