Ejemplo n.º 1
0
def test_existing_token_enabled_for_external_accounts(oauth_application, get, post, admin):
    UserEnterpriseAuth(user=admin, provider='radius').save()
    url = drf_reverse('api:oauth_authorization_root_view') + 'token/'
    with override_settings(RADIUS_SERVER='example.org', ALLOW_OAUTH2_FOR_EXTERNAL_USERS=True):
        resp = post(
            url,
            data='grant_type=password&username=admin&password=admin&scope=read',
            content_type='application/x-www-form-urlencoded',
            HTTP_AUTHORIZATION='Basic ' + smart_str(base64.b64encode(smart_bytes(':'.join([
                oauth_application.client_id, oauth_application.client_secret
            ])))),
            status=201
        )
        token = json.loads(resp.content)['access_token']
        assert AccessToken.objects.count() == 1

        with immediate_on_commit():
            resp = get(
                drf_reverse('api:user_me_list', kwargs={'version': 'v2'}),
                HTTP_AUTHORIZATION='Bearer ' + token,
                status=200
            )
            assert json.loads(resp.content)['results'][0]['username'] == 'admin'

    with override_settings(RADIUS_SERVER='example.org', ALLOW_OAUTH2_FOR_EXTERNAL_USER=False):
        with immediate_on_commit():
            resp = get(
                drf_reverse('api:user_me_list', kwargs={'version': 'v2'}),
                HTTP_AUTHORIZATION='Bearer ' + token,
                status=200
            )
            assert json.loads(resp.content)['results'][0]['username'] == 'admin'
Ejemplo n.º 2
0
def test_refresh_accesstoken(oauth_application, post, get, delete, admin):
    response = post(reverse('api:o_auth2_application_token_list', kwargs={'pk': oauth_application.pk}), {'scope': 'read'}, admin, expect=201)
    assert AccessToken.objects.count() == 1
    assert RefreshToken.objects.count() == 1
    token = AccessToken.objects.get(token=response.data['token'])
    refresh_token = RefreshToken.objects.get(token=response.data['refresh_token'])

    refresh_url = drf_reverse('api:oauth_authorization_root_view') + 'token/'
    response = post(
        refresh_url,
        data='grant_type=refresh_token&refresh_token=' + refresh_token.token,
        content_type='application/x-www-form-urlencoded',
        HTTP_AUTHORIZATION='Basic ' + smart_str(base64.b64encode(smart_bytes(':'.join([oauth_application.client_id, oauth_application.client_secret])))),
    )
    assert RefreshToken.objects.filter(token=refresh_token).exists()
    original_refresh_token = RefreshToken.objects.get(token=refresh_token)
    assert token not in AccessToken.objects.all()
    assert AccessToken.objects.count() == 1
    # the same RefreshToken remains but is marked revoked
    assert RefreshToken.objects.count() == 2
    new_token = json.loads(response._container[0])['access_token']
    new_refresh_token = json.loads(response._container[0])['refresh_token']
    assert AccessToken.objects.filter(token=new_token).count() == 1
    # checks that RefreshTokens are rotated (new RefreshToken issued)
    assert RefreshToken.objects.filter(token=new_refresh_token).count() == 1
    assert original_refresh_token.revoked  # is not None
Ejemplo n.º 3
0
def test_token_creation_disabled_for_external_accounts(oauth_application, post,
                                                       alice, allow_oauth,
                                                       status):
    UserEnterpriseAuth(user=alice, provider='radius').save()
    url = drf_reverse('api:oauth_authorization_root_view') + 'token/'

    with override_settings(RADIUS_SERVER='example.org',
                           ALLOW_OAUTH2_FOR_EXTERNAL_USERS=allow_oauth):
        resp = post(
            url,
            data='grant_type=password&username=alice&password=alice&scope=read',
            content_type='application/x-www-form-urlencoded',
            HTTP_AUTHORIZATION='Basic ' + smart_str(
                base64.b64encode(
                    smart_bytes(':'.join([
                        oauth_application.client_id,
                        oauth_application.client_secret
                    ])))),
            status=status)
        if allow_oauth:
            assert AccessToken.objects.count() == 1
        else:
            assert 'OAuth2 Tokens cannot be created by users associated with an external authentication provider' in smart_str(
                resp.content)  # noqa
            assert AccessToken.objects.count() == 0
Ejemplo n.º 4
0
def test_refresh_token_expiration_is_respected(oauth_application, post, get,
                                               delete, admin):
    response = post(reverse('api:o_auth2_application_token_list',
                            kwargs={'pk': oauth_application.pk}),
                    {'scope': 'read'},
                    admin,
                    expect=201)
    assert AccessToken.objects.count() == 1
    assert RefreshToken.objects.count() == 1
    refresh_token = RefreshToken.objects.get(
        token=response.data['refresh_token'])
    refresh_url = drf_reverse('api:oauth_authorization_root_view') + 'token/'
    short_lived = {
        'ACCESS_TOKEN_EXPIRE_SECONDS': 1,
        'AUTHORIZATION_CODE_EXPIRE_SECONDS': 1,
        'REFRESH_TOKEN_EXPIRE_SECONDS': 1
    }
    time.sleep(1)
    with override_settings(OAUTH2_PROVIDER=short_lived):
        response = post(refresh_url,
                        data='grant_type=refresh_token&refresh_token=' +
                        refresh_token.token,
                        content_type='application/x-www-form-urlencoded',
                        HTTP_AUTHORIZATION='Basic ' + smart_str(
                            base64.b64encode(
                                smart_bytes(':'.join([
                                    oauth_application.client_id,
                                    oauth_application.client_secret
                                ])))))
    assert response.status_code == 403
    assert b'The refresh token has expired.' in response.content
    assert RefreshToken.objects.filter(token=refresh_token).exists()
    assert AccessToken.objects.count() == 1
    assert RefreshToken.objects.count() == 1
Ejemplo n.º 5
0
    def _prepare(self, get, admin):
        if not self.__class__.JSON:
            url = drf_reverse('api:swagger_view') + '?format=openapi'
            response = get(url, user=admin)
            data = generate_swagger_object(response.data)
            if response.has_header('X-Deprecated-Paths'):
                data['deprecated_paths'] = json.loads(response['X-Deprecated-Paths'])
            data.update(response.accepted_renderer.get_customizations() or {})

            data['host'] = None
            data['schemes'] = ['https']
            data['consumes'] = ['application/json']

            revised_paths = {}
            deprecated_paths = data.pop('deprecated_paths', [])
            for path, node in data['paths'].items():
                # change {version} in paths to the actual default API version (e.g., v2)
                revised_paths[path.replace('{version}', settings.REST_FRAMEWORK['DEFAULT_VERSION'])] = node
                for method in node:
                    if path in deprecated_paths:
                        node[method]['deprecated'] = True
                    if 'description' in node[method]:
                        # Pop off the first line and use that as the summary
                        lines = node[method]['description'].splitlines()
                        node[method]['summary'] = lines.pop(0).strip('#:')
                        node[method]['description'] = '\n'.join(lines)

                    # remove the required `version` parameter
                    for param in node[method].get('parameters'):
                        if param['in'] == 'path' and param['name'] == 'version':
                            node[method]['parameters'].remove(param)
            data['paths'] = revised_paths
            self.__class__.JSON = data
Ejemplo n.º 6
0
def test_refresh_accesstoken(oauth_application, post, get, delete, admin):
    response = post(reverse('api:o_auth2_application_token_list',
                            kwargs={'pk': oauth_application.pk}),
                    {'scope': 'read'},
                    admin,
                    expect=201)
    token = AccessToken.objects.get(token=response.data['token'])
    refresh_token = RefreshToken.objects.get(
        token=response.data['refresh_token'])
    assert AccessToken.objects.count() == 1
    assert RefreshToken.objects.count() == 1

    refresh_url = drf_reverse('api:oauth_authorization_root_view') + 'token/'
    response = post(
        refresh_url,
        data='grant_type=refresh_token&refresh_token=' + refresh_token.token,
        content_type='application/x-www-form-urlencoded',
        HTTP_AUTHORIZATION='Basic ' + base64.b64encode(':'.join(
            [oauth_application.client_id, oauth_application.client_secret])))

    new_token = json.loads(response._container[0])['access_token']
    new_refresh_token = json.loads(response._container[0])['refresh_token']
    assert token not in AccessToken.objects.all()
    assert AccessToken.objects.get(token=new_token) != 0
    assert RefreshToken.objects.get(token=new_refresh_token) != 0
    refresh_token = RefreshToken.objects.get(token=refresh_token)
    assert refresh_token.revoked
Ejemplo n.º 7
0
def test_personal_access_token_creation(oauth_application, post, alice):
    url = drf_reverse('api:oauth_authorization_root_view') + 'token/'
    resp = post(
        url,
        data='grant_type=password&username=alice&password=alice&scope=read',
        content_type='application/x-www-form-urlencoded',
        HTTP_AUTHORIZATION='Basic ' + smart_str(base64.b64encode(smart_bytes(':'.join([oauth_application.client_id, oauth_application.client_secret])))),
    )
    resp_json = smart_str(resp._container[0])
    assert 'access_token' in resp_json
    assert 'scope' in resp_json
    assert 'refresh_token' in resp_json
Ejemplo n.º 8
0
    def get(self, request, format=None):
        ''' List supported API versions '''

        v2 = reverse('api:api_v2_root_view', kwargs={'version': 'v2'})
        data = OrderedDict()
        data['description'] = _('AWX REST API')
        data['current_version'] = v2
        data['available_versions'] = dict(v2 = v2)
        data['oauth2'] = drf_reverse('api:oauth_authorization_root_view')
        data['custom_logo'] = settings.CUSTOM_LOGO
        data['custom_login_info'] = settings.CUSTOM_LOGIN_INFO
        return Response(data)
Ejemplo n.º 9
0
    def _prepare(self, get, admin):
        if not self.__class__.JSON:
            url = drf_reverse('api:swagger_view') + '?format=openapi'
            response = get(url, user=admin)
            data = generate_swagger_object(response.data)
            if response.has_header('X-Deprecated-Paths'):
                data['deprecated_paths'] = json.loads(
                    response['X-Deprecated-Paths'])
            data.update(response.accepted_renderer.get_customizations() or {})

            data['host'] = None
            data['schemes'] = ['https']
            data['consumes'] = ['application/json']

            # Inject a top-level description into the OpenAPI document
            if os.path.exists(description_file):
                with open(description_file, 'r') as f:
                    data['info']['description'] = f.read()

            # Write tags in the order we want them sorted
            if os.path.exists(config_file):
                with open(config_file, 'r') as f:
                    config = yaml.load(f.read())
                    for category in config.get('categories', []):
                        tag = {'name': category['name']}
                        if 'description' in category:
                            tag['description'] = category['description']
                        data.setdefault('tags', []).append(tag)

            revised_paths = {}
            deprecated_paths = data.pop('deprecated_paths', [])
            for path, node in data['paths'].items():
                # change {version} in paths to the actual default API version (e.g., v2)
                revised_paths[path.replace(
                    '{version}',
                    settings.REST_FRAMEWORK['DEFAULT_VERSION'])] = node
                for method in node:
                    if path in deprecated_paths:
                        node[method]['deprecated'] = True
                    if 'description' in node[method]:
                        # Pop off the first line and use that as the summary
                        lines = node[method]['description'].splitlines()
                        node[method]['summary'] = lines.pop(0).strip('#:')
                        node[method]['description'] = '\n'.join(lines)

                    # remove the required `version` parameter
                    for param in node[method].get('parameters'):
                        if param['in'] == 'path' and param['name'] == 'version':
                            node[method]['parameters'].remove(param)
            data['paths'] = revised_paths
            self.__class__.JSON = data
Ejemplo n.º 10
0
def test_invalid_login():
    anon = auth.get_user(Client())
    url = drf_reverse('api:login')

    factory = APIRequestFactory()

    data = {'userame': 'invalid', 'password': '******'}

    request = factory.post(url, data)
    request.user = anon

    response = LoggedLoginView.as_view()(request)

    assert response.status_code == 401
Ejemplo n.º 11
0
def test_implicit_authorization(oauth_application, admin):
    oauth_application.client_type = 'confidential'
    oauth_application.authorization_grant_type = 'implicit'
    oauth_application.redirect_uris = 'http://test.com'
    oauth_application.save()
    data = {
        'response_type': 'token',
        'client_id': oauth_application.client_id,
        'client_secret': oauth_application.client_secret,
        'scope': 'read',
        'redirect_uri': 'http://test.com',
        'allow': True
    }

    request_client = Client()
    request_client.force_login(admin,
                               'django.contrib.auth.backends.ModelBackend')
    refresh_token_count = RefreshToken.objects.count()
    response = request_client.post(drf_reverse('api:authorize'), data)
    assert 'http://test.com' in response.url and 'access_token' in response.url
    # Make sure no refresh token is created for app with implicit grant type.
    assert refresh_token_count == RefreshToken.objects.count()
Ejemplo n.º 12
0
 def get(self, request, format=None):
     data = OrderedDict()
     data['authorize'] = drf_reverse('api:authorize')
     data['token'] = drf_reverse('api:token')
     data['revoke_token'] = drf_reverse('api:revoke-token')
     return Response(data)