def _get_access_token_jwt(self, request, content): extra_data = {} issuer = settings.JWT_ISSUER payload_enricher = getattr(settings, 'JWT_PAYLOAD_ENRICHER', None) if payload_enricher: request.user = get_access_token_model().objects.get( token=content['access_token']).user fn = import_string(payload_enricher) extra_data = fn(request) if 'scope' in content: extra_data['scope'] = content['scope'] id_attribute = getattr(settings, 'JWT_ID_ATTRIBUTE', None) if id_attribute: token = get_access_token_model().objects.get( token=content['access_token']) if token.application.authorization_grant_type != 'client-credentials': id_value = getattr(token.user, id_attribute, None) if not id_value: raise MissingIdAttribute() extra_data[id_attribute] = str(id_value) payload = generate_payload(issuer, content['expires_in'], **extra_data) token = encode_jwt(payload) return token
def _get_access_token_jwt(self, request, content): extra_data = {} issuer_shortname = settings.JWT_ISSUER issuer = settings.JWT_ISSUER_DOMAIN payload_enricher = getattr(settings, 'JWT_PAYLOAD_ENRICHER', None) request_params = list(request.POST.keys()) if payload_enricher: fn = import_string(payload_enricher) extra_data = fn(request) if 'scope' in content: extra_data['scope'] = content['scope'] extra_data['typ'] = "Bearer" extra_data['issuer_shortname'] = issuer_shortname if 'audience' in request_params: requested_audience = request.POST['audience'] token = get_access_token_model().objects.get( token=content['access_token'] ) audience_query = token.application.audience.all().only('identifier') all_audience = [audience.identifier for audience in audience_query] try: assert requested_audience in all_audience except AssertionError as ae: raise IncorrectAudience() else: extra_data['aud'] = requested_audience id_attribute = getattr(settings, 'JWT_ID_ATTRIBUTE', None) if id_attribute: token = get_access_token_model().objects.get(token=content['access_token']) token_user = token.user ## check the allowed scopes for user and content scopes try: assert token_user is not None id_value = getattr(token_user, id_attribute, None) if not id_value: raise MissingIdAttribute() except AssertionError as ae: id_value = token.application.client_id + "@clients" extra_data['sub'] = str(id_value) payload = generate_payload(issuer, content['expires_in'], **extra_data) headers = {'kid': settings.JWKS_KEY_ID} token = encode_jwt(payload, headers= headers) return token
def get_token_response(token_value=None): try: token = get_access_token_model().objects.get(token=token_value) except ObjectDoesNotExist: return HttpResponse( content=json.dumps({"active": False}), status=401, content_type="application/json", ) else: if token.is_valid(): data = { "active": True, "scope": token.scope, "exp": int(calendar.timegm(token.expires.timetuple())), } if token.application: data["client_id"] = token.application.client_id if token.user: data["username"] = token.user.get_username() data["role"] = token.user.role data["courses"] = list( token.user.courses.values_list("course_id", flat=True)) return HttpResponse( content=json.dumps(data), status=200, content_type="application/json", ) else: return HttpResponse( content=json.dumps({"active": False}), status=200, content_type="application/json", )
def get_userinfo_response(token_value=None): try: token = get_access_token_model().objects.get(token=token_value) except ObjectDoesNotExist: log.debug("Token not found for token_value %s" % token_value) return HttpResponse(content=json.dumps({"error": "invalid_token"}), status=401, content_type="application/json") else: if token.is_valid(): data = { 'provider': 'SciPost', 'uid': str(token.user.id), 'info': { 'name': token.user.get_full_name(), 'email': token.user.email, 'nickname': token.user.get_username(), 'first_name': token.user.get_short_name(), 'last_name': token.user.last_name, } } log.debug("Response for token %s:\n\t%s" % (token_value, data)) return HttpResponse(content=json.dumps(data), status=200, content_type="application/json") else: log.debug("Token %s is invalid" % token_value) return HttpResponse(content=json.dumps( {"error": "invalid_token"}), status=200, content_type="application/json")
def post(self, request, format=None): serializer = serializers.RefreshTokenSerializer(data=request.data) if serializer.is_valid(): if hasattr(request.data, "_mutable"): request.data._mutable = True app = Application.objects.all()[0] request.data.update({ "grant_type": "refresh_token", "client_id": app.client_id, "client_secret": app.client_secret }) url, headers, body, status = self.create_token_response(request) if status == 200: access_token = json.loads(body).get("access_token") if access_token is not None: token = get_access_token_model().objects.get( token=access_token) app_authorized.send(sender=self, request=request, token=token) response = HttpResponse(content=body, status=status) for k, v in headers.items(): response[k] = v return Response(json.loads(body), status=200) return Response(serializer.errors, status=400)
def post(self, request, *args, **kwargs): url, headers, body, status = self.create_token_response(request) if status == 200: body = json.loads(body) access_token = body.get("access_token") if access_token is not None: token = get_access_token_model().objects.get( token=access_token) app_authorized.send(sender=self, request=request, token=token) body = CustomResponse.build_response(True, body) body = json.dumps(body) response = HttpResponse(content=body, status=200) for k, v in headers.items(): response[k] = v return response else: body = json.loads(body) body['error'] = 'Username or Password is incorrect' body = CustomResponse.build_response(False, [body['error']]) body = json.dumps(body) response = HttpResponse(content=body, status=422) for k, v in headers.items(): response[k] = v return response
def access_token(application, scopes): AccessToken = get_access_token_model() return AccessToken.objects.create(scope=' '.join(scopes), expires=timezone.now() + timedelta(seconds=300), token='secret-access-token-key', application=application)
def generate_ats_from_at(self, request, access_token): code = self.find_code(request) grant = PaipassGrant.objects.all().get(code=code) prev_at_scopes = self.get_prev_access_token_scopes( request.client, request.user) # reassign all previous scopes to the new token. for prev_at_scope in prev_at_scopes: try: tmp_access_token = prev_at_scope.access_token except get_access_token_model().DoesNotExist: tmp_access_token = None prev_at_scope.access_token = access_token prev_at_scope.status = ATS_StatusChoices.APPROVED prev_at_scope.save() if tmp_access_token is not None: tmp_access_token.delete() apprs = AttributeApproval.objects.all().filter(grant=grant) for appr in apprs: qs_ats = AccessTokenScopes.objects.all().filter( access_token=access_token, attribute=appr.attribute) if qs_ats.count() < 1: ats = AccessTokenScopes.objects.create( access_token=access_token, attribute=appr.attribute, max_perms=appr.max_perms, status=ATS_StatusChoices.APPROVED, user=request.user) ats.save()
def setUp(self): oauth2_settings._SCOPES = {"read": "ler", "write": "escrever"} oauth2_settings.SCOPES = {"read": "ler", "write": "escrever"} oauth2_settings._DEFAULT_SCOPES = ['read'] self.dev_user = User.objects.create_user('dev_user', '*****@*****.**') self.test_user = User.objects.create_user('test_user', '*****@*****.**') self.app1 = Application.objects.create( name="meu app", description="minha descrição", user=self.dev_user, scope="read", redirect_uris="http://localhost.com http://test.com" ) self.app2 = Application.objects.create( name="meu app 2", description="minha descrição", user=self.dev_user, scope="write" ) self.tok1 = get_access_token_model().objects.create( user=self.test_user, token="1234567890", application=self.app2, expires=timezone.now() + datetime.timedelta(days=1), scope="read write" )
def setUp(self): self.userinfo = { 'username': '******', 'email': '*****@*****.**', 'password': '******', } self.user = User.objects.create_user(*self.userinfo.values()) self.profile = models.Profile.objects.create(user=self.user, age=19, gender='male') App, Token = get_application_model(), get_access_token_model() self.app = App.objects.create( client_type=App.CLIENT_PUBLIC, user=self.user, name="test_client_credentials_app", authorization_grant_type=App.GRANT_CLIENT_CREDENTIALS, ) self.token = Token.objects.create( user=self.user, scope="read write", expires=timezone.now() + timedelta(seconds=300), token="secret-access-token-key", application=self.app, ) self.client = Client()
def get_token_response(token_value=None): try: token = get_access_token_model().objects.get(token=token_value) except ObjectDoesNotExist: return HttpResponse(content=json.dumps({"active": False}), status=401, content_type="application/json") else: if token.is_valid(): data = { "active": True, "scope": token.scope, "exp": int(calendar.timegm(token.expires.timetuple())), } if token.application: data["client_id"] = token.application.client_id if token.user: data["user"] = UserSerializer(token.user).data return HttpResponse(content=json.dumps(data), status=200, content_type="application/json") else: return HttpResponse( content=json.dumps({"active": False}), status=200, content_type="application/json", )
def setUp(self): # TODO: usar factories con los modelos de auth Application = get_application_model() UserModel = get_user_model() AccessToken = get_access_token_model() oauth2_settings._SCOPES = [ "read", "write", "scope1", "scope2", "resource1" ] self.test_user = UserModel.objects.create_user("test_user", "*****@*****.**", "123456") self.dev_user = UserModel.objects.create_user("dev_user", "*****@*****.**", "123456") self.application = Application.objects.create( name="Test Application", redirect_uris="http://tests.com", user=self.dev_user, client_type=Application.CLIENT_CONFIDENTIAL, authorization_grant_type=Application.GRANT_AUTHORIZATION_CODE, ) self.access_token = AccessToken.objects.create( user=self.test_user, scope="read write", expires=datetime.datetime.now() + datetime.timedelta(seconds=300), token="secret-access-token-key", application=self.application) self.auth = self._create_authorization_header(self.access_token.token)
def collection_access(user): Application = get_application_model() application = Application.objects.create( name="Collection Test Access", allowed_scopes="collection:write", ) AccessToken = get_access_token_model() token = AccessToken.objects.create( user=user, scope="collection:write", expires=datetime.now() + timedelta(days=365), token=generate_token(), application=application, ) access_token = token.token blizzard_account = BlizzardAccount.objects.create( account_lo=123456789, account_hi=144115198130930503, region=BnetRegion.REGION_EU, user=user ) account_lo = blizzard_account.account_lo region = blizzard_account.region return account_lo, region, access_token
def test_get_queryset_should_return_an_access_token_queryset( self, validator, ): queryset = validator.get_queryset() assert isinstance(queryset, QuerySet) assert queryset.model == get_access_token_model()
def test_get_queryset_should_return_an_access_token_queryset( self, validator, ): queryset = validator.get_queryset() assert isinstance(queryset, QuerySet) assert queryset.model == get_access_token_model()
def get_relevant_models(self, request, pk): ApplicationModel = get_application_model() app = ApplicationModel.objects.all().get(id=pk) AccessTokenModel = get_access_token_model() access_token_qs = AccessTokenModel.objects.all().filter(application=app, user=request.user) return app, access_token_qs
def delete(self, request, *args, **kwargs): data = {} AccessToken = get_access_token_model() pk = kwargs['pk'] app = get_application_model().objects.all().get(id=pk) at = AccessToken.objects.all().get(application=app, user=request.user) at.delete() return Response(data, status=status.HTTP_200_OK)
def revoke(self, request, pk=None): access_tokens = get_access_token_model().objects.filter(application=pk) refresh_tokens = get_refresh_token_model().objects.filter( application=pk) for access_token in access_tokens: access_token.revoke() for refresh_token in refresh_tokens: refresh_token.revoke() return Response(status=status.HTTP_204_NO_CONTENT)
def access_token(test_user, application): AccessToken = get_access_token_model() token = AccessToken.objects.create(user=test_user, token="secret-access-token-key", expires=timezone.now() + timedelta(seconds=300), application=application) return token
def post(self, request): AccessToken = get_access_token_model() token = request.POST.get("token") if token: obj = get_object_or_404(AccessToken, token=token, user=self.request.user) obj.delete() messages.info(self.request, _("Access has been revoked.")) return redirect(self.next)
def get_valid_apps(self, user): access_tokens = get_access_token_model().objects.filter(user=user) valid_access_tokens = [ token for token in access_tokens if token.allow_scopes(self.permissions) ] return get_application_model().objects.exclude( webhook_url__isnull=True).exclude(webhook_url__exact='').filter( accesstoken__in=valid_access_tokens).distinct()
def check_grants(): AccessToken = get_access_token_model() token_count = AccessToken.objects.filter( expires__gt=timezone.now(), ).values('user', 'application').distinct().count() grant_count = DataAccessGrant.objects.all().count() return { "unique_tokens": token_count, "grants": grant_count, }
def update_grants(*args, **kwargs): AccessToken = get_access_token_model() # inefficient version tokens = AccessToken.objects.all() for token in tokens: if token.is_valid(): DataAccessGrant.objects.get_or_create( beneficiary=token.user, application=token.application, )
class DebugToken(generics.RetrieveAPIView): """Debug Token Returns useful info about the token """ versioning_class = None authentication_classes = [] permission_classes = [IsAdminUser] queryset = get_access_token_model().objects.all() lookup_field = 'token' lookup_url_kwarg = 'input_token' serializer_class = DebugTokenSerializer
class SSOAccessViewSet(viewsets.ReadOnlyModelViewSet): """ An `Access Token` is issued on successfull login and grants access to our API endpoints. """ serializer_class = SSOAccessReadOwnSerializer queryset = get_access_token_model().objects.all() permission_classes = [TokenHasScopeOrSuperUser] @action(detail=False, methods=["GET"]) def get_own(self, request): return get_access_token_model().objects.filter(user=request.user)
def approved_scopes(self, user): """ Returns the set of approved scopes by the user Represents the set that contains all scopes ever approved by the user to this app """ tokens = omodels.get_access_token_model().objects.filter( user=user, application=self) scopes = {} for token in tokens: for key, value in token.scopes.items(): scopes[key] = value return scopes
def get_user(request, *args, **kwargs): token_value = request.GET['access_token'] token = get_access_token_model().objects.get(token=token_value) user = token.user return HttpResponse(json.dumps({ 'id': user.id, 'username': user.username, 'first_name': user.first_name, 'last_name': user.last_name, 'email': user.email }), content_type='application/json')
def revoke_tokens(app_id, user_id): app = get_application_model().objects.filter(id=app_id) user = User.objects.get(pk=user_id) if app.exists(): app = app.first() refresh_tokens = get_refresh_token_model().objects.filter( user=user, application=app) for token in refresh_tokens: token.revoke() access_tokens = get_access_token_model().objects.filter( user=user, application=app) for token in access_tokens: token.revoke()
def get(self, request): import json token_value = request.headers['Authorization'][7:] # Bearer **** # token_value = request.META.get("HTTP_AUTHORIZATION")[7:] # tong shang from oauth2_provider.models import get_access_token_model token = (get_access_token_model().objects.select_related( "user", "application").get(token=token_value)) return HttpResponse( json.dumps({ "name": token.user.username, "username": token.user.username, "email": token.user.email }))
def create_access_token(user): token_expiration_time = timezone.now() + timedelta(minutes=60) token = get_access_token_model().objects.create( user=user, scope='read write packages', token='test{}{}'.format( user.id, int(token_expiration_time.timestamp()), ), application=get_application_model().objects.first(), expires=token_expiration_time, ) return token
def form_valid(self, form): user = self.request.user app_id = form.cleaned_data['app_id'] self.log.info('Revoking all oauth tokens for user %s, application %d', user, app_id) rt_model = oauth2_models.get_refresh_token_model() at_model = oauth2_models.get_access_token_model() gr_model = oauth2_models.get_grant_model() rt_model.objects.filter(user=user, application=app_id).delete() at_model.objects.filter(user=user, application=app_id).delete() gr_model.objects.filter(user=user, application=app_id).delete() return super().form_valid(form)
import datetime from urllib.parse import urlencode from django.contrib.auth import get_user_model from django.test import RequestFactory, TestCase from django.urls import reverse from django.utils import timezone from oauth2_provider.models import ( get_access_token_model, get_application_model, get_refresh_token_model ) from oauth2_provider.settings import oauth2_settings Application = get_application_model() AccessToken = get_access_token_model() RefreshToken = get_refresh_token_model() UserModel = get_user_model() class BaseTest(TestCase): def setUp(self): self.factory = RequestFactory() self.test_user = UserModel.objects.create_user("test_user", "*****@*****.**", "123456") self.dev_user = UserModel.objects.create_user("dev_user", "*****@*****.**", "123456") self.application = Application( name="Test Application", redirect_uris="http://localhost http://example.com http://example.org", user=self.dev_user, client_type=Application.CLIENT_CONFIDENTIAL,
def get(self, request, *args, **kwargs): # Note: This code is copied from https://github.com/evonove/django-oauth-toolkit/blob/34f3b7b3511c15686039079026165feaadb1b87d/oauth2_provider/views/base.py#L111 # Places that we have changed are noted with ***. application = None try: # *** Moved code to get the require_approval value earlier on so we can # circumvent our custom code in the case when auto_even_if_expired # isn't required. require_approval = request.GET.get( "approval_prompt", oauth2_settings.REQUEST_APPROVAL_PROMPT, ) if require_approval != 'auto_even_if_expired': return super(EdxOAuth2AuthorizationView, self).get(request, *args, **kwargs) scopes, credentials = self.validate_authorization_request(request) all_scopes = get_scopes_backend().get_all_scopes() kwargs["scopes_descriptions"] = [all_scopes[scope] for scope in scopes] kwargs['scopes'] = scopes # at this point we know an Application instance with such client_id exists in the database application = get_application_model().objects.get(client_id=credentials['client_id']) content_orgs = ApplicationOrganization.get_related_org_names( application, relation_type=ApplicationOrganization.RELATION_TYPE_CONTENT_ORG ) kwargs['application'] = application kwargs['content_orgs'] = content_orgs kwargs['client_id'] = credentials['client_id'] kwargs['redirect_uri'] = credentials['redirect_uri'] kwargs['response_type'] = credentials['response_type'] kwargs['state'] = credentials['state'] self.oauth2_data = kwargs # following two loc are here only because of https://code.djangoproject.com/ticket/17795 form = self.get_form(self.get_form_class()) kwargs['form'] = form # If skip_authorization field is True, skip the authorization screen even # if this is the first use of the application and there was no previous authorization. # This is useful for in-house applications-> assume an in-house applications # are already approved. if application.skip_authorization: uri, headers, body, status = self.create_authorization_response( request=self.request, scopes=" ".join(scopes), credentials=credentials, allow=True) return HttpResponseUriRedirect(uri, application.get_allowed_schemes()) # *** Changed the if statement that checked for require_approval to an assert. assert require_approval == 'auto_even_if_expired' tokens = get_access_token_model().objects.filter( user=request.user, application=kwargs['application'], # *** Purposefully keeping this commented out code to highlight that # our version of the implementation does NOT filter by expiration date. # expires__gt=timezone.now(), ).all() # check past authorizations regarded the same scopes as the current one for token in tokens: if token.allow_scopes(scopes): uri, headers, body, status = self.create_authorization_response( request=self.request, scopes=" ".join(scopes), credentials=credentials, allow=True) return HttpResponseUriRedirect(uri, application.get_allowed_schemes()) # render an authorization prompt so the user can approve # the application's requested scopes return self.render_to_response(self.get_context_data(**kwargs)) except OAuthToolkitError as error: return self.error_response(error, application)
from django.contrib.auth import get_user_model from django.contrib.auth.models import AnonymousUser from django.http import HttpResponse from django.test import RequestFactory, TestCase from django.test.utils import modify_settings, override_settings from django.utils.timezone import now, timedelta from oauth2_provider.backends import OAuth2Backend from oauth2_provider.middleware import OAuth2TokenMiddleware from oauth2_provider.models import get_access_token_model, get_application_model UserModel = get_user_model() ApplicationModel = get_application_model() AccessTokenModel = get_access_token_model() class BaseTest(TestCase): """ Base class for cases in this module """ def setUp(self): self.user = UserModel.objects.create_user("user", "*****@*****.**", "123456") self.app = ApplicationModel.objects.create( name="app", client_type=ApplicationModel.CLIENT_CONFIDENTIAL, authorization_grant_type=ApplicationModel.GRANT_CLIENT_CREDENTIALS, user=self.user ) self.token = AccessTokenModel.objects.create( user=self.user, token="tokstr", application=self.app,
def get(self, request, *args, **kwargs): # Copy/Pasta'd from oauth2_provider.views.BaseAuthorizationView.get try: scopes, credentials = self.validate_authorization_request(request) # all_scopes = get_scopes_backend().get_all_scopes() # kwargs["scopes"] = scopes # kwargs["scopes_descriptions"] = [all_scopes[scope] for scope in scopes] # at this point we know an Application instance with such client_id exists in the database # TODO: Cache this! application = get_application_model().objects.get(client_id=credentials["client_id"]) kwargs["client_id"] = credentials["client_id"] kwargs["redirect_uri"] = credentials["redirect_uri"] kwargs["response_type"] = credentials["response_type"] kwargs["state"] = credentials["state"] try: kwargs["application"] = { "name": application.applicationinfo.get_visible_name(), } if application.applicationinfo.icon: kwargs["application"]['image'] = application.applicationinfo.icon.url if application.applicationinfo.website_url: kwargs["application"]["url"] = application.applicationinfo.website_url app_scopes = [s for s in re.split(r'[\s\n]+', application.applicationinfo.allowed_scopes) if s] except ApplicationInfo.DoesNotExist: app_scopes = ["r:profile"] kwargs["application"] = dict( name=application.name, scopes=app_scopes ) filtered_scopes = set(app_scopes) & set(scopes) kwargs['scopes'] = list(filtered_scopes) all_scopes = get_scopes_backend().get_all_scopes() kwargs['scopes_descriptions'] = {scope: all_scopes[scope] for scope in scopes} self.oauth2_data = kwargs # Check to see if the user has already granted access and return # a successful response depending on "approval_prompt" url parameter require_approval = request.GET.get("approval_prompt", oauth2_settings.REQUEST_APPROVAL_PROMPT) # If skip_authorization field is True, skip the authorization screen even # if this is the first use of the application and there was no previous authorization. # This is useful for in-house applications-> assume an in-house applications # are already approved. if application.skip_authorization: success_url = self.get_authorization_redirect_url(" ".join(kwargs['scopes']), credentials) return Response({ 'success_url': success_url }) elif require_approval == "auto" and not request.user.is_anonymous: tokens = get_access_token_model().objects.filter( user=request.user, application=application, expires__gt=timezone.now() ).all() # check past authorizations regarded the same scopes as the current one for token in tokens: if token.allow_scopes(scopes): success_url = self.get_authorization_redirect_url(" ".join(kwargs['scopes']), credentials) return Response({ 'success_url': success_url }) return Response(kwargs) except OAuthToolkitError as error: return Response({ 'error': error.oauthlib_error.description }, status=HTTP_400_BAD_REQUEST)