diff --git a/passbook/core/settings.py b/passbook/core/settings.py index 529379050..318844972 100644 --- a/passbook/core/settings.py +++ b/passbook/core/settings.py @@ -74,6 +74,7 @@ INSTALLED_APPS = [ 'passbook.otp.apps.PassbookOTPConfig', 'passbook.captcha_factor.apps.PassbookCaptchaFactorConfig', 'passbook.hibp_policy.apps.PassbookHIBPConfig', + 'passbook.pretend.apps.PassbookPretendConfig', ] # Message Tag fix for bootstrap CSS Classes diff --git a/passbook/core/views/access.py b/passbook/core/views/access.py index dc42c25d3..254c651bf 100644 --- a/passbook/core/views/access.py +++ b/passbook/core/views/access.py @@ -1,7 +1,8 @@ """passbook access helper classes""" from logging import getLogger -from django.http import Http404 +from django.contrib import messages +from django.utils.translation import gettext as _ from passbook.core.models import Application @@ -11,14 +12,18 @@ class AccessMixin: """Mixin class for usage in Authorization views. Provider functions to check application access, etc""" + # request is set by view but since this Mixin has no base class + request = None + def provider_to_application(self, provider): """Lookup application assigned to provider, throw error if no application assigned""" try: return provider.application except Application.DoesNotExist as exc: - # TODO: Log that no provider has no application assigned - LOGGER.warning('Provider "%s" has no application assigned...', provider) - raise Http404 from exc + messages.error(self.request, _('Provider "%(name)s" has no application assigned' % { + 'name': provider + })) + raise exc def user_has_access(self, application, user): """Check if user has access to application.""" diff --git a/passbook/oauth_provider/settings.py b/passbook/oauth_provider/settings.py index f3aeacb3e..8c3156d6d 100644 --- a/passbook/oauth_provider/settings.py +++ b/passbook/oauth_provider/settings.py @@ -22,6 +22,8 @@ OAUTH2_PROVIDER = { 'SCOPES': { 'openid:userinfo': 'Access OpenID Userinfo', # 'write': 'Write scope', - # 'groups': 'Access to your groups' + # 'groups': 'Access to your groups', + 'user:email': 'GitHub Compatibility: User E-Mail', + 'read:org': 'GitHub Compatibility: User Groups', } } diff --git a/passbook/pretend/__init__.py b/passbook/pretend/__init__.py new file mode 100644 index 000000000..e69de29bb diff --git a/passbook/pretend/apps.py b/passbook/pretend/apps.py new file mode 100644 index 000000000..3a823b13f --- /dev/null +++ b/passbook/pretend/apps.py @@ -0,0 +1,11 @@ +"""passbook pretend config""" +from django.apps import AppConfig + + +class PassbookPretendConfig(AppConfig): + """passbook pretend config""" + + name = 'passbook.pretend' + label = 'passbook_pretend' + verbose_name = 'passbook Pretender' + mountpoint = '' diff --git a/passbook/pretend/urls.py b/passbook/pretend/urls.py new file mode 100644 index 000000000..e140c9f9a --- /dev/null +++ b/passbook/pretend/urls.py @@ -0,0 +1,16 @@ +"""passbook pretend urls""" +from django.urls import include, path +from oauth2_provider.views import TokenView + +from passbook.oauth_provider.views.oauth2 import PassbookAuthorizationView +from passbook.pretend.views.github import GitHubUserView + +github_urlpatterns = [ + path('login/oauth/authorize', PassbookAuthorizationView.as_view(), name='github-authorize'), + path('login/oauth/access_token', TokenView.as_view(), name='github-access-token'), + path('user', GitHubUserView.as_view(), name='github-user'), +] + +urlpatterns = [ + path('', include(github_urlpatterns)) +] diff --git a/passbook/pretend/views/__init__.py b/passbook/pretend/views/__init__.py new file mode 100644 index 000000000..e69de29bb diff --git a/passbook/pretend/views/github.py b/passbook/pretend/views/github.py new file mode 100644 index 000000000..ea5277517 --- /dev/null +++ b/passbook/pretend/views/github.py @@ -0,0 +1,55 @@ +"""passbook pretend GitHub Views""" +from django.http import JsonResponse +from django.views import View + + +class GitHubUserView(View): + """Emulate GitHub's /user API Endpoint""" + + def get(self, request): + """Emulate GitHub's /user API Endpoint""" + return JsonResponse({ + "login": request.user.username, + "id": request.user.pk, + "node_id": "", + "avatar_url": "", + "gravatar_id": "", + "url": "", + "html_url": "", + "followers_url": "", + "following_url": "", + "gists_url": "", + "starred_url": "", + "subscriptions_url": "", + "organizations_url": "", + "repos_url": "", + "events_url": "", + "received_events_url": "", + "type": "User", + "site_admin": False, + "name": "%s %s" % (request.user.first_name, request.user.last_name), + "company": "", + "blog": "", + "location": "", + "email": request.user.email, + "hireable": False, + "bio": "", + "public_repos": 0, + "public_gists": 0, + "followers": 0, + "following": 0, + "created_at": request.user.date_joined, + "updated_at": request.user.date_joined, + "private_gists": 0, + "total_private_repos": 0, + "owned_private_repos": 0, + "disk_usage": 0, + "collaborators": 0, + "two_factor_authentication": True, + "plan": { + "name": "None", + "space": 0, + "private_repos": 0, + "collaborators": 0 + } + })