def test_get_scopes(self):
        token = ApiToken(scopes=1)
        assert token.get_scopes() == ['project:read']

        token = ApiToken(scopes=4, scope_list=['project:read'])
        assert token.get_scopes() == ['project:read']

        token = ApiToken(scope_list=['project:read'])
        assert token.get_scopes() == ['project:read']
    def test_is_expired(self):
        token = ApiToken(expires_at=None)
        assert not token.is_expired()

        token = ApiToken(expires_at=timezone.now() + timedelta(days=1))
        assert not token.is_expired()

        token = ApiToken(expires_at=timezone.now() - timedelta(days=1))
        assert token.is_expired()
Example #3
0
    def test_by_api_token(self):
        token = ApiToken()
        for n in range(100):
            assert not ratelimits.for_organization_member_invite(
                Organization(id=randint(0, 100000)),
                "{}@example.com".format(randint(0, 1000000)),
                auth=token,
            )

        assert ratelimits.for_organization_member_invite(
            Organization(id=1), "*****@*****.**")
Example #4
0
    def test_by_api_token(self):
        token = ApiToken(id=1)
        for n in range(5):
            assert not ratelimits.for_organization_member_invite(
                Organization(id=randint(0, 100000)),
                f"{randint(0, 1000000)}@example.com",
                auth=token,
                config=RELAXED_CONFIG,
            )

        assert ratelimits.for_organization_member_invite(
            Organization(id=1),
            "*****@*****.**",
            auth=token,
            config=RELAXED_CONFIG)
Example #5
0
    def approve(self, request, application, **params):
        try:
            with transaction.atomic():
                ApiAuthorization.objects.create(
                    application=application,
                    user=request.user,
                    scopes=(
                        reduce(or_, (
                            getattr(ApiAuthorization.scopes, k)
                            for k in params['scopes']
                        ))
                        if params['scopes']
                        else 0
                    ),
                )
        except IntegrityError:
            if params['scopes']:
                auth_scopes = F('scopes')
                for s in params['scopes']:
                    auth_scopes = auth_scopes.bitor(
                        getattr(ApiAuthorization.scopes, s)
                    )

                ApiAuthorization.objects.filter(
                    application=application,
                    user=request.user,
                ).update(
                    scopes=auth_scopes,
                )

        if params['response_type'] == 'code':
            grant = ApiGrant(
                user=request.user,
                application=application,
                redirect_uri=params['redirect_uri'],
            )
            if params['scopes']:
                for s in params['scopes']:
                    setattr(grant.scopes, s, True)
            grant.save()
            return self.redirect_response(
                params['response_type'],
                params['redirect_uri'],
                {
                    'code': grant.code,
                    'state': params['state'],
                },
            )
        elif params['response_type'] == 'token':
            token = ApiToken(
                application=application,
                user=request.user,
                refresh_token=None,
            )
            for s in params['scopes']:
                setattr(token.scopes, s, True)
            token.save()

            return self.redirect_response(
                params['response_type'],
                params['redirect_uri'],
                {
                    'access_token': token.token,
                    'expires_in': (timezone.now() - token.expires_at).total_seconds(),
                    'expires_at': token.expires_at.strftime('%Y-%m-%dT%H:%M:%S.%fZ'),
                    'token_type': 'bearer',
                    'scope': ' '.join(k for k, v in token.scopes.iteritems() if v),  # NOQA
                    'state': params['state'],
                },
            )
Example #6
0
    def post(self, request):
        grant_type = request.POST.get("grant_type")

        if grant_type == "authorization_code":
            client_id = request.POST.get("client_id")
            redirect_uri = request.POST.get("redirect_uri")
            code = request.POST.get("code")

            if not client_id:
                return self.error(request, "invalid_client",
                                  "missing client_id")

            try:
                application = ApiApplication.objects.get(
                    client_id=client_id, status=ApiApplicationStatus.active)
            except ApiApplication.DoesNotExist:
                return self.error(request, "invalid_client",
                                  "invalid client_id")

            try:
                grant = ApiGrant.objects.get(application=application,
                                             code=code)
            except ApiGrant.DoesNotExist:
                return self.error(request, "invalid_grant", "invalid grant")

            if grant.is_expired():
                return self.error(request, "invalid_grant", "grant expired")

            if not redirect_uri:
                redirect_uri = application.get_default_redirect_uri()
            elif grant.redirect_uri != redirect_uri:
                return self.error(request, "invalid_grant",
                                  "invalid redirect_uri")

            token = ApiToken.from_grant(grant)
        elif grant_type == "refresh_token":
            refresh_token = request.POST.get("refresh_token")
            scope = request.POST.get("scope")
            client_id = request.POST.get("client_id")

            if not refresh_token:
                return self.error(request, "invalid_request")

            # TODO(dcramer): support scope
            if scope:
                return self.error(request, "invalid_request")

            if not client_id:
                return self.error(request, "invalid_client",
                                  "missing client_id")

            try:
                application = ApiApplication.objects.get(
                    client_id=client_id, status=ApiApplicationStatus.active)
            except ApiApplication.DoesNotExist:
                return self.error(request, "invalid_client",
                                  "invalid client_id")

            try:
                token = ApiToken.objects.get(application=application,
                                             refresh_token=refresh_token)
            except ApiToken.DoesNotExist:
                return self.error(request, "invalid_grant", "invalid token")

            token.refresh()
        else:
            return self.error(request, "unsupported_grant_type")

        return HttpResponse(
            json.dumps({
                "access_token":
                token.token,
                "refresh_token":
                token.refresh_token,
                "expires_in":
                int((token.expires_at - timezone.now()).total_seconds())
                if token.expires_at else None,
                "expires_at":
                token.expires_at,
                "token_type":
                "bearer",
                "scope":
                " ".join(token.get_scopes()),  # NOQA
                "user": {
                    "id": six.text_type(token.user.id),
                    # we might need these to become scope based
                    "name": token.user.name,
                    "email": token.user.email,
                },
            }),
            content_type="application/json",
        )
Example #7
0
    def post(self, request):
        grant_type = request.POST.get('grant_type')

        if grant_type == 'authorization_code':
            client_id = request.POST.get('client_id')
            client_secret = request.POST.get('client_secret')
            redirect_uri = request.POST.get('redirect_uri')
            code = request.POST.get('code')

            if not client_id:
                return self.error('invalid_client')

            if not client_secret:
                return self.error('invalid_client')

            try:
                application = ApiApplication.objects.get(
                    client_id=client_id,
                    status=ApiApplicationStatus.active,
                )
            except ApiApplication.DoesNotExist:
                return self.error('invalid_client')

            if not constant_time_compare(client_secret, application.client_secret):
                return self.error('invalid_client')

            try:
                grant = ApiGrant.objects.get(application=application, code=code)
            except ApiGrant.DoesNotExist:
                return self.error('invalid_grant')

            if grant.is_expired():
                return self.error('invalid_grant')

            if not redirect_uri:
                redirect_uri = application.get_default_redirect_uri()
            elif grant.redirect_uri != redirect_uri:
                return self.error('invalid_grant')

            token = ApiToken.from_grant(grant)
        elif grant_type == 'refresh_token':
            refresh_token = request.POST.get('refresh_token')
            scope = request.POST.get('scope')
            client_id = request.POST.get('client_id')
            client_secret = request.POST.get('client_secret')

            if not refresh_token:
                return self.error('invalid_request')

            # TODO(dcramer): support scope
            if scope:
                return self.error('invalid_request')

            if not client_id:
                return self.error('invalid_client')

            if not client_secret:
                return self.error('invalid_client')

            try:
                application = ApiApplication.objects.get(
                    client_id=client_id,
                    status=ApiApplicationStatus.active,
                )
            except ApiApplication.DoesNotExist:
                return self.error('invalid_client')

            if not constant_time_compare(client_secret, application.client_secret):
                return self.error('invalid_client')

            try:
                token = ApiToken.objects.get(
                    application=application,
                    refresh_token=refresh_token,
                )
            except ApiToken.DoesNotExist:
                return self.error('invalid_grant')

            token.refresh()
        else:
            return self.error('unsupported_grant_type')

        return HttpResponse(
            json.dumps(
                {
                    'access_token': token.token,
                    'refresh_token': token.refresh_token,
                    'expires_in': (timezone.now() - token.expires_at).total_seconds(),
                    'expires_at': token.expires_at,
                    'token_type': 'bearer',
                    'scope': ' '.join(token.get_scopes()),  # NOQA
                    'user': {
                        'id': six.text_type(token.user.id),
                        # we might need these to become scope based
                        'name': token.user.name,
                        'email': token.user.email,
                    },
                }
            ),
            content_type='application/json'
        )
Example #8
0
    def post(self, request):
        grant_type = request.POST.get('grant_type')

        if grant_type == 'authorization_code':
            client_id = request.POST.get('client_id')
            client_secret = request.POST.get('client_secret')
            redirect_uri = request.POST.get('redirect_uri')
            code = request.POST.get('code')

            if not client_id:
                return self.error('invalid_client')

            if not client_secret:
                return self.error('invalid_client')

            try:
                application = ApiApplication.objects.get(
                    client_id=client_id,
                    status=ApiApplicationStatus.active,
                )
            except ApiApplication.DoesNotExist:
                return self.error('invalid_client')

            if not constant_time_compare(client_secret, application.client_secret):
                return self.error('invalid_client')

            try:
                grant = ApiGrant.objects.get(application=application, code=code)
            except ApiGrant.DoesNotExist:
                return self.error('invalid_grant')

            if grant.is_expired():
                return self.error('invalid_grant')

            if not redirect_uri:
                redirect_uri = application.get_default_redirect_uri()
            elif grant.redirect_uri != redirect_uri:
                return self.error('invalid_grant')

            token = ApiToken.from_grant(grant)
        elif grant_type == 'refresh_token':
            refresh_token = request.POST.get('refresh_token')
            scope = request.POST.get('scope')
            client_id = request.POST.get('client_id')
            client_secret = request.POST.get('client_secret')

            if not refresh_token:
                return self.error('invalid_request')

            # TODO(dcramer): support scope
            if scope:
                return self.error('invalid_request')

            if not client_id:
                return self.error('invalid_client')

            if not client_secret:
                return self.error('invalid_client')

            try:
                application = ApiApplication.objects.get(
                    client_id=client_id,
                    status=ApiApplicationStatus.active,
                )
            except ApiApplication.DoesNotExist:
                return self.error('invalid_client')

            if not constant_time_compare(client_secret, application.client_secret):
                return self.error('invalid_client')

            try:
                token = ApiToken.objects.get(
                    application=application,
                    refresh_token=refresh_token,
                )
            except ApiToken.DoesNotExist:
                return self.error('invalid_grant')

            token.refresh()
        else:
            return self.error('unsupported_grant_type')

        return HttpResponse(json.dumps({
            'access_token': token.token,
            'refresh_token': token.refresh_token,
            'expires_in': (timezone.now() - token.expires_at).total_seconds(),
            'expires_at': token.expires_at,
            'token_type': 'bearer',
            'scope': ' '.join(token.get_scopes()),  # NOQA
            'user': {
                'id': six.text_type(token.user.id),
                # we might need these to become scope based
                'name': token.user.name,
                'email': token.user.email,
            },
        }), content_type='application/json')